/* Copyright (c) 2008 Extentech Inc. All Rights Reserved

##### Sheetster&trade; Web Application #####

This file is a part of the Sheetster&trade; Web Application

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

If you would like to redistribute this software in a closed-source application,
dual-licensed commercial versions are available from Extentech.

For a fully supported and redistributable commercial license, 
please visit www.extentech.com or contact us at:

 sales@extentech.com
 Extentech Inc.
 1032 Irving Street #910
 San Francisco, CA 94122
 415-759-5292
 
*/
/**
	SheetsterWindowing is a class that handles all of the standard windowing calls within
	the DocsFree heetster interface.
	
**/
sheetsterWindowing = Class.create();
sheetsterWindowing.prototype = {
	
	initialize: function(){
		this.filedrop_menu;		
		this.menuheight = 115;
		this.acc = null; // the accordion menu
		this.erring = false;
		this.singledoc = false;
		this.activeWindow = null;
		this.titleBarHolder = null;
		
		// TODO: make dynamic
		this.editBarHolder = null;
		this.cellRangeBox = null;
		
		// this.miniStatusBarHolder = null;
		// this.miniErrorBarHolder = null;
		this.theme = 'sheetster'; // the webapp theme
		this.edit_menu_scroll_offset = 0;
		// check size holders
		this.whold = 0;
		this.hhold = 0;
		this.lhold = 0;
		
		/**
		 * only use a single showError instance.
		 */
		try{
			if( typeof(showError) == "undefined"){
				var rb = parent.showError;
				if(typeof(rb) != "undefined"){
					this.showError = rb;
				}else{
					showError = this.showError;
					parent.showError = this.showError;
				}
			}
			
			if(typeof(showStatus) == "undefined"){
				var sb = parent.showStatus;
				if(typeof(sb) != "undefined"){
					this.showStatus = sb;
				}else{
					showStatus = this.showStatus;
					parent.showStatus = this.showStatus;
				}
			
			}
		}catch(e){
			// in embedded/iframe situations we will get acccess denied errors on parent
			showError = this.showError;
			showStatus = this.showStatus;
		}

		
	},
	
	/**
	 * attaches mouseover behavior to ui buttons
	 * 
	 * TODO: complete this... not yet functional
	 * 
	 * @return
	 */
	initializeButtons: function(){
		var hs= $$('div.btn_sm');
		
	 	for (i= 0; i < hs.length;i++) {
 	 	//	alert(hs[i].innerHTML);
 	 		hs[i].removeClass('btn_sm');
 	 		hs[i].addClass('btn_orangesm');
 		}
		
	},
	
	/**
	 * show/hide the navigation div
	 * also resized doc contents.
	 *
	 */
	toggleNavDiv: function(){
		
		ajaxBind('nav_div','/uimodules/docs/docs_explorer.jsp');
		
		if(!this.navopen){
			this.resizeGrid(this.getActiveDocument(),300);
			$('nav_div').setStyle('zIndex',100);
			this.navopen = true;
		}else{
			this.resizeGrid(this.getActiveDocument());
			this.navopen = false;
		}
	},
	
	/**
		initialize the Accordion Ribbon menu
	*/
	initializeMenu: function(){
	   	var auto_normal_accordion_options={
	   		panelHeight:'auto',
	   		mode:'free',
	 		onLoadShowTab:-1, 
			roundCorners:false,
			tabLocation:'top',
	   		tabSpacing :'2',
	   		
	   		borderColor: (is.ie?'#EEEEEE':'null'),
	   		borderSize:'0',
		    
	   		transitionColor:'blue',

		    hoverTextColor:'#EEEEEE',
			hoverBg       :'#111111',
         	
		    collapsedTextColor:'#222222',
		    collapsedBg       :'#E5E9EE',

		    expandedTextColor:'#000000',
	   		expandedBg       :'#FDFDFD',
	   		duration:.5
	   	};
	
		//Ajax modification
		uiWindowing.acc = new Rico.Accordion($('auto_normal_accordion'), auto_normal_accordion_options);
		   
		   // show it!
		$('mainmenu').style.visibility='visible';
		
		try{
			var sid = $('signon_div');
			if(sid !=null)
				sid.style.visibility='visible';
		}catch(e){;}
	},
	
	/**
		disable/enable the Accordion Ribbon menu
	*/
	showMenu: function(show){

		// <div id='darkenMenu' style="display:none;"></div>
		// <div class="marcoBlack" id="mainmenu" style="visibility:hidden; z-index:1; width:100%;">

		// show it!
		try{
			var disabler = parent.document.getElementById('darkenMenu');
			if(disabler != null){
				if(!show)
					disabler.style.visibility='visible';
				else
					disabler.style.visibility='hidden';
			}
		}catch(e){;}
	
	},

	
	
	/**
	 * show or hide the sign on div
	 * 
	 * @param whether to show or hide
	 */
	showSignOnDiv: function(show){
		if(show){
			$('login_button').show();
			$('signon_div').show();
		}else{
			$('login_button').hide();
			$('signon_div').hide();
		}
	},
	
	/**
		opens the doc in appropriate editor, or the url in a window
		
		@param description of the document
		@url of the page to open (non-doc)
		@theme to use for display
		@scrollbars flag to show vertical scroll for overflow
		@mime_type chooses the appropriate doc editor
	*/
	openDoc: function(desc, memeid, theme, scrollbars, mime_type){
	
		var url = "/none";
		var isgrid = false;
	
		// only do mime type if defined
		if(mime_type!=null){
	
			try{
				parent.uiWindowing.switchEditMenu(mime_type);
				// showStatus('Opening doc type: ' + mime_type);
			}catch(e){;}
			
			// alert('Opening doc type: ' + mime_type);
			
			// have to switch between the following...
			if(mime_type == "doc"){ // its a doc
				url = '/doc_editor/doc.jsp?meme_id=' + memeid;
				url+= '&maximize=true';					
				isgrid = false;
			}else if(mime_type == "workbook"){ // its  a grid!
				
				// use REST call
				url = '/workbook/id/'+memeid+'/xhtml/workbook/get/0/';
				
				// url = '/grid/grid.jsp?meme_id=' + memeid;
				
				url+= '?maximize=true&noribbon=true';
				isgrid=true;
			}else if(mime_type == "article"){ // its  a meme article
				// non doc_detail calls will have meme_id already specified...
				if(url.indexOf("meme_id")==-1){
					url = '/uimodules/docs/docs_detail.jsp?meme_id=' + memeid;
					url+= '&showall=true';
				}
				isgrid=false;
			}else if(mime_type == "list"){ // its  a meme article
				url = memeid + '&showall=true';
				isgrid=false;
			//	alert(url);
			}
		}
		
		if(typeof contentframe!='undefined'){
			if(typeof parent.contentframe!='undefined' && 
					parent.contentframe.location !=null){
				parent.contentframe.location.href = url;
			}else{
				contentframe.location.href= url
			}
			document.title = desc;
			return;
		}
	
		try{ // now set the contents of the frame if any
			if(typeof contentframe!='undefined'){
				if(contentframe.location!=null)
					contentframe.location.href = url;
				else
					contentframe.location = url;

				document.title = desc;
				return;
			}
		}catch(e){;}
		
		try{
			var winx = parent.createWindow(desc,url,theme);
			this.activesheet = winx;
	
			// maximize it
			if(mime_type!="list")
				parent.uiWindowing.maximizeActiveSheet(winx);
		}catch(e){
			//parent.showError('could not open:'+e.toString());
		}
	},
	
	
	/**
		change the edit menu for different mime types
		
		@param the mime type name to open
	*/
	switchEditMenu: function(mime_type){
	
		if(mime_type == 'doc'){
			$('doceditmenubox').show();
			$('editmenubox').hide();
		}else if(mime_type == 'workbook'){
			$('doceditmenubox').hide();
			$('editmenubox').show();
		}
	},
	
	/**
		Open the Accordion menu to a specfic tab.
		
		Unfortunately does not work reliably if tabs are opened already.
	**/   
	accordionGo: function(index){
		if(this.acc){ // happens on meme_id load
			if(this.acc.lastExpandedTab != null){
				if(this.acc.lastExpandedTab.content == null){ // collapsed
					this.acc.showTabByIndex(index);
				}else if(this.acc.lastExpandedTab.content.offsetHeight < 100){ // edit not already open
					 this.acc.showTabByIndex(index);
				}else{  // already open
					// do nothing
				}
			}else{
				this.acc.showTabByIndex(index);
			}
		}
	},
	
	
	/**
		show the Login Dialog
		
		@param title for the dialog
		@param the url for the dialog contents
		@param the theme to display
	*/
	createLoginDialog: function(title, module, theme){
	
		var htx = this.getBrowserHeight();
		var wdx = this.getBrowserWidth();
			
		var winx = new Window(title, { 
				title: title, 
				className: theme,
				url:module, 
				width:wdx, 
				height:htx, 
				zIndex:100, 
				opacity:1,
				resizable: false,
		  		closable: false,
			  	minimizable:       false,
			  	maximizable:       false,
			  	draggable:         false,			
	       	  	destroyOnClose:    true,
			  hideEffectOptions: {duration:0},
			  showEffectOptions: {duration:0}
			});
		winx.content.setStyle({overflow: "hidden"});
		//winx.setContent("select")
		winx.setDestroyOnClose(true);
		winx.showCenter();
		
		var _this = this;
		onresize = function() {
			_this.resizeGrid(winx, 0, -25);
		}; 
		
		winx.show(true);
	},
	
	
	/**
	 get the width of the browser window
	*/ 
	getBrowserWidth: function(){
	// detect browsers and determine window size	
	var myWidth = 0, myHeight = 0;
	

		// Handle MindTouch-Deki lightbox sizing
		try	{
			var mt_div = parent.document.getElementById('TB_window');
			if(mt_div!=null){
				showStatus('sheetsterWindowing using TB_window width:' + mt_div.getWidth());
				return mt_div.getWidth();
			}
		}catch(e){
			//parent.showError('could not open:'+e.toString());
		}
	  if( typeof( window.innerWidth ) == 'number' ) {
	    //Non-IE
	    return window.innerWidth;
	  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
	    //IE 6+ in 'standards compliant mode'
	    return document.documentElement.clientWidth;
	  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
	    //IE 4 compatible
	    return document.body.clientWidth;
	  }
	},
	
	/**
	 get the height of the browser window
	*/ 
	getBrowserHeight: function(){
		if( typeof( window.innerWidth ) == 'number' ) {
		    //Non-IE
		    return window.innerHeight;
		  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
		    //IE 6+ in 'standards compliant mode'
		    return document.documentElement.clientHeight;
		  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
		    //IE 4 compatible
		    return document.body.clientHeight;
		  }
	},
	
/**
	Get the active doc that is being worked on.  Note that this class could
	be instantiated either in the grid iframe, where we have a 'sheet' variable
	available, or outside of the iframe where we could have multiple sheets.
	
	This class is meant to be called from another Window object
**/
	getActiveDoc: function(){
		if(this.activeWindow!=null)
			return this.activeWindow;
		
		// get the top-level parent...
		var par = top;
		
		// first, find the windows
		var winz = null;
		try{
			winz = par.Windows;
		} catch(e) {
		}				
		
		if(winz == null &&
				(typeof Windows!='undefined')){
			winz = Windows;
		}
		var activeWin = winz.getFocusedWindow();
		
		if(activeWin != null
		&& activeWin.sheet == null){	// no luck
			winz.windows.each(function(item) {
				if(item.sheet !=null){
					activeWin = item;
				}
			}); 
		}
		return activeWin;
	},

	/**
		Get the active document that is open or in edit mode
		
		Returns a javascript Document object
	 **/
	getActiveDocument: function(){
		var framedoc = this.getActiveDoc();
		if(framedoc == null)
			return null;
			
		// we have a handle to the window from the top
		
		try{
			if(framedoc.content.contentWindow &&
					framedoc.content.contentWindow.book!=null)
	        	return framedoc.content.contentWindow.book;
		}catch(e){;}

		// we have a handle to the window from the top
		// now deal with scope issues
		if(framedoc.book){ 
			return framedoc.book;
		}else if(framedoc.parent && (framedoc.parent.book!=null)){
			return framedoc.parent.book;
		}

		var theId = framedoc.getId();
		theId = theId+'_content';
		var activeElem =  $(theId);
		if(activeElem == null)
			activeElem = framedoc;
		
		if(activeElem.contentWindow!=null){
			if(activeElem.contentWindow !=null){
				return activeElem.contentWindow;
			}
		}
		
		if(activeElem == null
				||(typeof(activeElem) == 'undefined')){
			if(this.activeWindow!=null
					&&(typeof(activeWindow) == 'undefined')){ // always returns last opened grid
				return this.activeWindow;
			}else{
				showStatus("Please select an active Document.");
				return null;
			}
		}	
		return activeElem;

		
	},
	
	
	/**
		Get the active sheet that is being worked on.  Note that this class could
		be instantiated either in the grid iframe, where we have a 'sheet' variable
		available, or outside of the iframe where we could have multiple sheets.
		
		Returns a javascript SheetHandle object
	**/
	getActiveSheet: function(){
		
		var activeDoc = this.getActiveDocument();
		if(typeof(activeDoc.selectedSheet)!='undefined'){
			return activeDoc.selectedSheet;
		}		
		return activeDoc.sheet;
	},
		
		
	/**
		Scrolls the ribbon menu
		
		since the menu width is 1600px, we can keep a variable
		to track scroll and update the tooltip menus...
		
	*/
	scrollRibbon: function(vx, dvname){
		var offset = 400; // must be evenly divisible into edit div width
		var direction = 'x';
		
		if(vx==null){
			vx='left';
		}
		try{
			if(vx == 'left'){
				var scrx = new Effect.Scroll(dvname,{x:offset, mode:'relative'});
				// offset the tooltip windows
				TooltipManager.options.shiftX = TooltipManager.options.shiftX - offset;
			}else if(vx == 'right'){
				offset *= -1;
				var scrx = new Effect.Scroll(dvname,{x:offset, mode:'relative'});
				// offset the tooltip windows
				TooltipManager.options.shiftX = TooltipManager.options.shiftX - offset;
			}else if(vx == 'top'){
				var scrx = new Effect.Scroll(dvname,{y:offset, mode:'relative'});
				// offset the tooltip windows
				TooltipManager.options.shiftY = TooltipManager.options.shiftY - offset;
			}else if(vx == 'down'){
				offset *= -1;
				var scrx = new Effect.Scroll(dvname,{y:offset, mode:'relative'});
				// offset the tooltip windows
				TooltipManager.options.shiftY = TooltipManager.options.shiftY - offset;
				
			}
		}catch(e){
			; // swallow
		}
	},	
		
	/* expand the cell edit box for editing large txt
	*/
	toggleExpandEditBar: function(){
		try{
			var topbar = this.activeWindow.topbar;
			var editbox = topbar.down('#celleditbox');
			var button = topbar.down('#celleditexpandbutton');
			
			if ('true' == editbox.getAttribute('expanded')) {
				editbox.setStyle({height: '24px'});
				topbar.setStyle({height: '24px'});
				button.src='/themes/icons/down.gif';
				editbox.setAttribute( 'expanded', 'false' );
			} else {
				editbox.setStyle({height: '198px'});
				topbar.setStyle({height: '200px'});
				button.src='/themes/icons/up.gif';
				editbox.setAttribute( 'expanded', 'true' );
			}
		} catch (caught) {
			Logger.error('toggleExpandEditBar failed', caught);
		}
	},
	
	/* toggle edit box
	*/
	toggleEditBar: function(){
		try{
			var elem = $('editbar');
			elem.toggle();
		}catch(e){;}
	},
	
	
	
	/**
		Get the active cell that is focused.  Note that this class could
		be instantiated either in the grid iframe, where we have a 'sheet' variable
		available, or outside of the iframe where we could have multiple sheets.
		
		Returns a javascript CellHandle object
	**/
	getActiveCell: function(){
		return this.getActiveSheet().getSelection().getFocus();
	},
	
	/**
	Get the active cellrange that is focused.  Note that this class could
	be instantiated either in the grid iframe, where we have a 'sheet' variable
	available, or outside of the iframe where we could have multiple sheets.
	
	Returns a javascript CellRange object
	**/
	getActiveCellRange: function(){
		return this.getActiveSheet().getSelection().getRange();
	},
	
	/**
	 * Maximizes the active sheet, pulls out the edit bar
	 	ribbon
	 */
	maximizeActiveSheet: function(actv){
		if(actv!=null){
			this.activeWindow = actv;
		}else if(actv==null)
			actv = this.getActiveDoc();
		if(actv==null){
			showStatus("Please select an active document.");
			return;
		}
		
		// check for a doc
		if (!actv.content.contentWindow) return;
		if (!actv.content.contentWindow.book == null) return;
		
		this.resetAlertDialogs();
		try{
			var fwin = $('filedrop_menu');
			if(fwin !=null)
				fwin.hide();
				
			var erbr = $('errorbar');
			if(erbr !=null)
				erbr.hide();
					
		}catch(e){;}
		
		// get the top bar of the window
		var titleBar = $(actv.getId() + "_top");
		if(titleBar == null){ // handle upload window
			// synched with changes to: locale_strings.get("menu_accordion_3")
			try{
				titleBar = $(upload_title + "_top");
				actv = parent.Windows.getWindow(upload_title);
			}catch(e){;}
			// alert("maximizing: "+ actv.getId());		
		}

		// set the doc title
		try{
			parent.document.title = actv.getId();
		}catch(e){;}
	
		// flag the window as maximized
		actv.maximized=true;
			
		try{
			actv._storeLocation();
			actv.centered = false;
		}catch(e){
			// showError('storelocation:'+e.toString()); // sucks 
		}
		
		this.resizeGrid(actv);
		
		// set the top and bottom bars
		var el2 = this.editBarHolder;
		if(el2==null){
			this.editBarHolder = $('editbar');
			el2 = this.editBarHolder;
			this.cellRangeBox =  $('cellrangebox');
		}else{
			this.cellRangeBox.setValue('');
			this.getActiveDocument().getNamedRanges();
		}
		
		//if(this.miniErrorBarHolder == null){
		//	this.miniErrorBarHolder = $('minierrorbar');
		//}
		//if(this.miniStatusBarHolder == null){
		//	this.miniStatusBarHolder = $('ministatusbar');
		//}
		
		/* the window buttons... toggle */
		var bcls = $(actv.getId() + '_close');
		var bmin = $(actv.getId() + '_minimize');
		var bmax = $(actv.getId() + '_maximize');
		var _this = this;
		var _actv = actv;
		try{
			
			// does not fix wierd chrome scrollbars behind close button
			// bcls.setStyle({ overflow:'hidden' });
			
			// bcls.toggle();
			// bmin.toggle();
			
			bmax.onclick = function() {
				_this.restoreActiveSheet();
				return false;
			}
			
			// prompt save of changes...
			bcls.onclick = function() {
				try{
					_this.getActiveDocument().promptSave(actv);
				}catch(e){;}
			}
			
		}catch(e){
			//alert('sheetsterWindowing.maixmizeAvtiveSheet() btn handlers failed:'+e);
		}
		
		/**
			create the formula/namedrange/message bar, replace titlebar with it
		*/
		try{
			// mini bars
		    //titleBar.appendChild(this.miniErrorBarHolder);
		    //titleBar.appendChild(this.miniStatusBarHolder);
			
		    if (titleBar.firstChild){
		    	try{
		    		this.titleBarHolder = titleBar.removeChild(titleBar.firstChild);
		    	}catch(e){;}
		    	titleBar.appendChild(el2);
			}else{
		       	titleBar.appendChild(el2);
			}

			try{
				el2.show();
			}catch(e){;}
			
	    }catch(e){;}
	    
	    		
		// ensure no stuff from prior sheets
		try{
			$('celleditbox').innerHTML = '';
		}catch(e){;}
		

		// show the edit menu
		try{
			this.accordionGo(1);
		}catch(e){
			showError('problem opening edit ribbon menu:'+e);
		}
		
		onresize = function() {
			_this.resizeGrid(_actv);
		}; 
		
		
		// re-init the cursor 
		try{
			var currSheet = this.getActiveSheet();
			currSheet.cellEditor.initUI();
		}catch(e){;}	
	},
	
	/** grid fits the window

	*/
	resizeGrid: function(gridwin, offset_left, offset_top){
		
		try{
			if((typeof gridwin!='undefined') && uiWindowing)
				gridwin = uiWindowing.getActiveDoc();
		}catch(e){;}
	
		if(gridwin ==null)
			return;
			
		
		// detect browsers and determine window size	
		var myWidth = this.getBrowserWidth();
		var myHeight = this.getBrowserHeight();
		var myLeft = 0;
		var myTop = 0;
		
		var winW = 0, winH = 0, menuoff = 18;
		 if (!is.ie) { // var from sheet_header_inc
		  winW = myWidth -0;
		  winH = myHeight -10;
		 }else{
		  winW = myWidth  +0;
		  winH = myHeight +5;
		  menuoff = 35;
		 }
		if(winW > 0){
			var el = gridwin;
			
			this.menuheight = 0;
			try{
				this.menuheight = $('mainmenu').getHeight();
			}catch(e){;}
			
			
			// if(this.menuheight == 0)
			if(offset_top){
				this.menuheight = offset_top;
				menuoff = offset_top;
				myTop = offset_top;
			}else{			
				this.menuheight = 115; // ack:it's dynamic!
			}
			var gridheight = winH-(this.menuheight + menuoff);
	
			if(offset_left){
				winW -= offset_left;
				myLeft = offset_left;
			}
			
		
			// alert(gridheight);
			if(el!=null){
				var currSheet = this.getActiveSheet();
					try{
						if(typeof(currSheet.book)!='undefined' &&
								currSheet.book.lightbox &&
								is.ff){ // hack for mindtouch lightbox sizing bug in FIREFOX ONLY
							el.setSize((winW+8),gridheight+12); 
							el.setLocation((this.menuheight-12),myLeft-4);
						}else{
							el.setSize(winW,gridheight); // 18 w/o bar
							el.setLocation((this.menuheight),myLeft-10);
						}
					}catch(e){
						el.setSize(winW,gridheight); // 18 w/o bar
						el.setLocation((this.menuheight),myLeft-10);
					}					
					try {
						if (!currSheet.initialLoad) currSheet.checkLoad();
					} catch (e) {}
				}
			}
		this.whold = myWidth;
		this.hhold = myHeight;
		this.lhold = myLeft;
	},
	
	/**
	 * restores the active sheet and other windows
	 */
	restoreActiveSheet: function(){
		var actv = this.getActiveDoc(); 
		if(actv==null){
			showStatus("Please select an active spreadsheet.");
			return;
		}
		this.resetAlertDialogs();
		
		// show the file menu
		try{
		 	this.accordionGo(0);
		}catch(e){
			showError('problem opening file ribbon menu:'+e);
		}
		
		
		// flag the window as un-maximized
		actv.maximized=false;

		// unset the title		
		parent.document.title = 'Powered by Sheetster';

		// reset the bar
		this.resetTitleBar();		

		// put others up
		try{
			this.setWindowsVisible(true,actv);
			actv._restoreLocation();
		}catch(es){
			showError('restoreActiveSheet restoring window layouts failed:'+es); // problem?
		}
		
		// remove event handler
		window.onresize = function() {};
		this.singledoc=false;
	},

	/**
	 * TODO: implement this?  not high priority now that name dropdown bugs are fixed...
	 * 
	 * reset the titlebar
	 * 
	 * @memberOf {TypeName} 
	 * @return {TypeName} 
	 */
	resetTitleBarNEW: function(){
		var actv = this.getActiveDoc(); 
		if(actv==null){
			showStatus("Please select an active spreadsheet.");
			return;
		}
		
		var titleBar = $(actv.getId() + "_top");
		try{ // remove existing
			titleBar.removeChild($('editbar'));
		}catch(x){
			// showError("Could Not remove editbar from titlebar: " + x.toString());
		}
		
		try{
			// create the edit bar
			this.editbar = $('editbar'); 
			
			// create the namedRangeBar
			var namedRangeBar = new Element( 'div', {
				'id': 'namedRangeDiv',
				'class': 'cell'
			});
			namedRangeBar.setStyle({float:'left', width:'150px', height:'24px'});

			// create the namedRangeBox
			var namedRangeBox = new Element( 'input', {
				'type':'text',
				'id': 'cellrangebox',
				'class': 'listMenu'
			});
			
			namedRangeBox.setStyle({float:'left', marginLeft:'0px', width:'112px', height:'24px'});
			
			
			// create the namedRangeExpandButton
			var namedRangeExpandButton = new Element( 'img', {
				'src':'/themes/icons/down.gif',
				'id': 'namesexpandbutton',
				'class': 'rteImage',
				'align':'absMiddle'
			});
			namedRangeExpandButton.setStyle({float:'left', margin:'0px', border:'0px'});
			namedRangeExpandButton.onClick="getActiveSheet().dropNameDiv()";
			
			namedRangeBar.appendChild(namedRangeBox);
			namedRangeBar.appendChild(namedRangeExpandButton);
			this.editbar.appendChild(namedRangeBar);
			// end name div

			// create the function button
			var functionButton = new Element( 'img', {
				'src':'/themes/icons/function.png',
				'title':'Formula Functions',
				'id': 'namesexpandbutton',
				'class': 'rteImage'
			});
			functionButton.setStyle({float:'left', marginLeft:'0px'});
			// TODO: implement  <%=locale_strings.get("menu_accordion_7")%>
			// functionButton.onclick= createSizedDialogWindow('Formula Functions',400, 350,'/uimodules/function_list.jsp','extentech');

			// create the edit area button
			var cellEditArea = new Element( 'textarea', {
				'id': 'celleditbox',
				'class': 'listMenu'
			});
			cellEditArea.setStyle({float:'left', marginLeft:'0px', resize:'none', overflow:'hidden', whiteSpace:'pre', width:'50%', height:'24px'});
			this.editbar.appendChild(cellEditArea);
			
			// create the dropdown edit button
			var editDropDownButton = new Element( 'img', {
				'src':'/themes/icons/down.gif',
				'title':'click to expand the cell edit box',
				'id': 'celleditexpandbutton',
				'class': 'rteImage',
				'align':'absmiddle'
			});
			editDropDownButton.setStyle({margin:'0px', border:'0px'});
			editDropDownButton.onClick="uiWindowing.toggleExpandEditBar();"
			
			this.editbar.appendChild(editDropDownButton);

			// create the edit commit button
			var editCommitButton = new Element( 'img', {
				'src':'/themes/icons/checkmark.png',
				'title':'click to set the cell value',
				'id': 'celleditcommit',
				'class': 'rteImage',
				'align':'absmiddle'
			});
			editCommitButton.setStyle({margin:'0px', border:'0px'});
			editCommitButton.onClick="uiWindowing.getActiveSheet().getEditor().submit();"
			
			this.editbar.appendChild(editCommitButton);
			// end editbar
			
		}catch(es){
			try{
	    		titleBar.removeChild(titleBar.firstChild);
	    	}catch(e){;}
			// showError('restoreActiveSheet creating edit bar failed: '+es); // problem!
		}
		
		try{
			// restore the title bar
			titleBar.appendChild(this.editbar);
			this.editbar.show();
			
		}catch(es){
			// debug('restoreActiveSheet titleBarHolder failed: '+es); // problem?
		}
	
		try{
			var bcls = $(actv.getId() + '_close');
			bcls.onclick = function(){
				bcls.onclick();
				_this.reloadFileMenu();
				return false;	
			}
			
			
			var bmin = $(actv.getId() + '_minimize');
			var bmax = $(actv.getId() + '_maximize');
			
			var _actv = actv;
			var _this = this;
			bmax.onclick = function() {
				_this.maximizeActiveSheet(_actv);
				return false;
			}
		}catch(es){;}
			// showError('restoreActiveSheet toggling window buttons failed:'+es); // problem?
		
	},
	
	
	/**
	 * reset the titlebar
	 * 
	 * @memberOf {TypeName} 
	 * @return {TypeName} 
	 */
	resetTitleBar: function(){
		var actv = this.getActiveDoc(); 
		if(actv==null){
			showStatus("Please select an active spreadsheet.");
			return;
		}
		
		
		var titleBar = $(actv.getId() + "_top");
		try{
			//this.editBarHolder = titleBar.removeChild($('editbar'));
			this.editBarHolder.hide();
			// this.miniErrorBarHolder = titleBar.removeChild($('minierrorbar'));
			// this.miniStatusBarHolder = titleBar.removeChild($('ministatusbar'));
		}catch(es){
			try{
	    		titleBar.removeChild(titleBar.firstChild);
	    	}catch(e){;}
			debug('restoreActiveSheet editBarHolder failed:'+es); // problem?
		}
		
		try{
			// restore the title bar
			titleBar.appendChild(this.titleBarHolder);
		}catch(es){
			debug('restoreActiveSheet titleBarHolder failed:'+es); // problem?
		}
	
		try{
			var bcls = $(actv.getId() + '_close');
			bcls.onclick = function(){
				bcls.onclick();
				_this.reloadFileMenu();
				return false;	
			}
			
			
			var bmin = $(actv.getId() + '_minimize');
			var bmax = $(actv.getId() + '_maximize');
			
			var _actv = actv;
			var _this = this;
			bmax.onclick = function() {
				_this.maximizeActiveSheet(_actv);
				return false;
			}
		}catch(es){;}
			// showError('restoreActiveSheet toggling window buttons failed:'+es); // problem?
		
	},
	
	/**
	 * resets the text on the status and error alert dialogs
	 * 
	 */
	resetAlertDialogs: function(){

		try{
			var bar = $('errorbar');
			if(bar != null)
				bar.innerHTML = '';
		}catch(e){;}
	},

	// reload the file menu
	reloadFileMenu: function(){
		try{
			if(typeof(filedrop_menu) != 'undefined')
				filedrop_menu.setURL('/uimodules/docs/docs_explorer.jsp');
		}catch(e){
			this.createFileMenu('Docs Navigator', 'extentech');
		}
	},

	/**
	 * file menu dropping window
	 * 
	 * @param the theme to use
	 * @param the title of the dialog window
	 */ 
 	createFileMenu: function(theme,name){
		
		// reopen existing... faster and cleaner
		if(typeof(filedrop_menu)=='undefined'){
			
			// Windows with an URL as content
			filedrop_menu = new Window('filedrop_menu', {
				 title: name,
				 top:120,
				 className:theme,
				 left:10, 
				 width:500, 
				 zIndex:0,
				 height:500,
				 gridX:10,
				 gridY:10,
				 draggable: true,
				 resizable: true,
				 minimizable:true,
				 maximizable:true,
				 closable:true,
				 overflow:'hidden',
				 url:'/uimodules/docs/docs_explorer.jsp',
				 
				 destroyOnClose: false,
				 hideEffectOptions: {duration:0},
				 showEffectOptions: {duration:0}
				});
		}
		
		//filedrop_menu.setDestroyOnClose(true);
		
		filedrop_menu.content.setStyle({ overflow:'hidden' });
		filedrop_menu.toFront();
		filedrop_menu.show();
	},


	
	
	/**
	  show or hide all windows other than 
	  the window passed in
	*/
	setWindowsVisible: function(b, main) {
	  
		for(x=0;x<Windows.windows.length;x++){
			try{
			var winx = Windows.windows[x];
				if(winx != main){
					if(b)
						winx.show();
					else
						winx.hide();
				}
			}catch(e){;}
		}
	},
	
	/**
	 minimize windows
	*/
	cascadeWindows: function() {  
		var sz = 30;
		var windx = null;
		if(Windows!=null)
			windx = Windows.windows;
		else
			windx = parent.Windows.windows;
		
		for(x=0;x<windx.length;x++){
			var winx = windx[x];
			winx._storeLocation();
			winx.setSize(400,300);
			// Sets window location
	  		winx.setLocation((sz*x)+100, 400+(sz*x));
		}
	},
	
	/**
	 minimize windows
	*/
	stackWindows: function() {  
		var sz = 40;
		var windx = null;
		if(Windows!=null)
			windx = Windows.windows;
		else
			windx = parent.Windows.windows;
		
		for(x=0;x<windx.length;x++){
			var winx = windx[x];
			winx.setZIndex(30);
			winx.setSize(400,600);
			winx.setLocation((sz*x), 400); 
			winx.minimize();
		}
	},
	
	/**
	close and reset windows
	*/
	closeAllWindows: function() {
		try{
			parent.Windows.closeAll();
		}catch(e){;}
		Windows.closeAll();
	},


	/**
	 * create the error bars, set styles etc.
	 */
	createBars: function(type){
		bar = document.createElement('div');
		bar = Element.extend(bar);
		bar.setAttribute('id', type + 'bar');
		bar.style.bottom = '0';
		bar.style.display = 'none';
		bar.style.width = '100%';
		bar.style.position = 'absolute';
		bar.className=type+'bar';
		bar.style.zIndex = '100';
		document.body.appendChild(bar);
	},
	
	/** Shows an error message.
	 * The message will also be sent to {@link Logger#error}.
	 * 
	 * @param {string} content the HTML message to display
	 * @param {Error} [error] an error to pass on to <code>Logger</code>
	 */
	showError: function (content, error) {
		if(content == undefined || content == '')
			return; // handle spurious calls
		errBar = $('errorbar');
		// get the error bars
		if(errBar==null){ // no bars, create...
			try{
				errBar = window.parent.document.getElementById('errorbar');
			}catch(ex){;}
			if(errBar == null) // still not there
				uiWindowing.createBars('error');
			errBar = $('errorbar');
		}
		// show the error bar
		errBar.innerHTML = '<img src="/themes/icons/tango/32x32/status/dialog-error.png" align="absmiddle" alt="ERROR:">&nbsp;' + content;	
		createStatusPopup(errBar, false);
		
		// log to the console
		if (window.Logger)
			Logger.error( "USER: " + this._convertHTMLMessage( content ), error );
	},
	
	/** Shows a warnining message.
	 * The message will also be sent to {@link Logger#warn}.
	 * 
	 * @param {string} content the HTML message to display
	 * @param {Error} [error] an error to pass on to <code>Logger</code>
	 */
	showWarning: function (content, error) {
		if(content == undefined || content == '')
			return; // handle spurious calls
		warningBar = $('warningbar');
		// get the error bars
		if(warningBar==null){ // no bars, create...
			try{
				warningBar = window.parent.document.getElementById('warningbar');
			}catch(ex){;}
			if(warningBar == null) // still not there
				uiWindowing.createBars('warning');
			warningBar = $('warningbar');
		}
		// show the error bar
		warningBar.innerHTML = '<img src="/themes/icons/tango/32x32/status/dialog-warning.png" align="absmiddle" alt="WARNING:">&nbsp;' + content;	
		createStatusPopup(warningBar, false);
		
		// log to the console
		if (window.Logger)
			Logger.warning( "USER: " + this._convertHTMLMessage( content ), error );
	},
	
	/**
	 * hide and reset the error/status bar
	 */
	hideBar: function(bnm){
		
		var iBar = $(bnm+'bar');
		if(typeof(iBar) == 'undefined'){
			try{
				iBar = window.parent.document.getElementById(bnm+'bar');
			}catch(e){;}
		}
		if(typeof(iBar) != 'undefined'){
			try{
				if(iBar.getHeight()>0){ // only fold if not folding/folded
					new Effect.Fold(iBar);
					iBar.innerHTML = '';
				}
			}catch(e){;}
		}
	},

	/** Shows a status message.
	 * The message will also be sent to {@link Logger#info}.
	 * 
	 * @param {string} content the HTML message to display
	 */
	showStatus: function(content){
		if(content == undefined || content == '')
			return; // handle spurious calls

		statBar = $('statusbar');
		// get the error bars
		if(statBar==null){ // no bars, create...
			try{
				statBar = window.parent.document.getElementById('statusbar');
			}catch(ex){;}
			if(statBar == null) // still not there
				uiWindowing.createBars('status');
			statBar = $('statusbar');
		}
		
		// show the info bar
		statBar.innerHTML = '<img src="/themes/icons/tango/32x32/status/dialog-information.png" style="position:static;" align="left" alt="INFO:">&nbsp;' + content;	
		createStatusPopup(statBar,true);
		
		// log to the console
		if (window.Logger)
			Logger.info( "USER: " + this._convertHTMLMessage( content ) );
	}, 
	
	_convertHTMLMessage: function (message) {
		message = message.replace( /<br\s*\/?>/ig, '\n' );
		message = message.replace( /&nbsp;/ig, ' ' );
		return message;
	}
};
var uiWindowing = new sheetsterWindowing();
