
var SYNTHIS_DEBUG = false;
var SYNTHIS_DEBUG_LEFT = 10;
var GLOBAL = {ver:'1.0'};

function calcSize() {alert('This function is going away soon, please do not call it anymore');}

// This is to stop the javascript error that occurr when the iframe detail html is displayed
// the details html is calling this function
// EXAMPLE:  parent.setCurrentWireframe( 'd86feb40-351-110-048-1bde0b40fd27082' );
parent.setCurrentWireframe = Prototype.emptyFunction;

/*--------------------------------------------------------------------------*/
/*  CLASS ProcessWebsite  */
/*--------------------------------------------------------------------------*/
var ProcessWebsite = Class.create();
ProcessWebsite.prototype = {
initialize:          function(modelUri, servletPath, mapsPath, diaUuid, diaImg, imgPath, imgWidth, imgHeight, title, data)
                     {
                        this.debug = new DebugLogger('debugArea');
                        this.debug.log('ProcessWebsite.initialize()');
                        
                        // offset used for window size
                        this.offsetWidth = 73;
						this.offsetHeight = 208;
						
						// window top left corner
						this.winTop = 123;
						this.winLeft = 20;
						
						// the width of the details window
						this.detailsWinWidth = 280;
						this.detailsWinPadding = 20;
                        
                        // if the window is maximzed or not (see toggleWindowMaximize)
                        this.maximized = false;
                        
                        this.modelUri = modelUri;
                        this.diaUuid = diaUuid;                        
                        this.data = data || {};
                        this.data.id = this.diaUuid
                        
                        this.imgWidth = imgWidth;
                        this.imgHeight = imgHeight;
                        //this.imgSrc = diaUuid + '.jpg';
                        this.imgSrc = diaImg;                        
                        this.pixelImgSrc = imgPath + '/pixel.gif';
                        this.diagramIndicator = imgPath + '/diagramIndicator.gif';
                        this.diagramIndicatorHasDec = imgPath + '/diagramIndicatorHasDec.gif';
                        this.expandImgSrc = imgPath + '/btn_expand_sm.gif';
                        this.expandImgSrc_inactive = imgPath + '/btn_expand_sm_inactive.gif';
                        this.collapseImgSrc = imgPath + '/btn_collapse_sm.gif';
                        this.collapseImgSrc_inactive = imgPath + '/btn_collapse_sm_inactive.gif';
                        this.htmlDocumentImgSrc = imgPath + '/decorators/htmlDocument.gif';
                        this.detailModeId = 'processWebsiteDetailMode';
                        this.overlayLinkLocationId = 'processWebsiteOverlayLinks';
                        
                        this.servletPath = servletPath;
                        
                        ///this.imgElement.src = "/diagram?uri=http://www.synthis.com/r4/elements/processmap/8eb609b0-989-b10-048-447b0f0a207b43c&modelUri=http://www.synthis.com/r4/modeler/8e7d4a58-989-b10-048-447b0f0a207b43c&s="+this.zPercentage;
                        this.imgUrlPrefix = this.servletPath + '/diagram?uri='+this.diaUuid+'&modelUri='+this.modelUri+'&p=0&s=';
                        this.printUrl = mapsPath + '/print?e=' + this.diaUuid;
                        
                        this.title = title;
                        if(this.title == null){
                        	this.title = "";
                        }
                        
                        this.hotSpots = [];
                        this.selectedHotSpot = null;
                        
                        this.overlays = [];
                        
                        window.onresize = this.onResize.bindAsEventListener(this);
                     },
                     
render:              function(){
                        
                        Windows.addObserver(new WindowObserver());
                        
                        dims = this.getWindowDimensions();
                        
                        options = Object.extend(new DefaultWinOptions(),
                              {
                              width:dims.width,
                              height:dims.height,
                              closable: false,
                              minimizable: false,
                              maximizable: false
                              });
                                                
                        this.win = new Window('pwWindow', options);
                        this.element = this.win.getContent();
                                       
                        //this.win.setTitle('<b>'+this.title+'</b>');  
                        this.win.setTitle('&nbsp;');                      
                        this.win.setLocation(this.winTop,this.winLeft);
                                               
                        this.initInnerWinArea();                        
                        this.initCookie();
                        this.initDragBox();
                        this.initHotSpots();
                        this.initOverlays(); 
                      	this.initZoomer();
                      	this.initWinButtons();

                        w = this.win;
                        setTimeout(function() {w.show();}, 5);
                        
                        pw = this;
                        setTimeout(function() {pw.initZoomLevel();}, 25);
                        
                     },

a2Id:	 		     function(str){
						return this.win.getId() + '_pw_' + str;
					 },

initInnerWinArea:	 function(){
						
						var buf = new StringBuffer();
						
						var rightColBuf = new StringBuffer();
						rightColBuf.append('  <table cellspacing="0" cellpadding="0" border="0"><tr><td>');
                        rightColBuf.append('<a href="../../../processnarrative?processmap='+this.data.id+'#'+this.data.id+'-Diagram" target="_blank">Process Narrative</a> | '+this.buildMoreInfoLinkHTML(this.data));
						rightColBuf.append('  </td>');
						rightColBuf.append('  <td align="right" width="30">');
			//			if ( this.data.comment != '' || this.data.links != '' || this.data.ownerList != '' || this.data.requirementsList != '' ) {
							rightColBuf.append('	<a id="'+this.a2Id('ToggleDiaDetailsLink')+'" href="#" onclick="javascript:this.pw.toggleWinTop();return false;">');
							rightColBuf.append('	<img id="'+this.a2Id('ToggleDiaDetailsImg')+'" src="'+this.expandImgSrc+'" border="0"></a>');
                     	//}
                     	//else {
                     	//	rightColBuf.append('	<img id="'+this.a2Id('ToggleDiaDetailsImg')+'" src="'+this.expandImgSrc_inactive+'" border="0">');
                     	//}
						rightColBuf.append('  </td></tr></table>');
						
						// TOP
						buf.append('<table cellspacing="0" cellpadding="0" border="0" width="100%">');
						buf.append('<tr><td><img src="'+this.pixelImgSrc+'" width="10px"></td>');
						buf.append('<td width="100%">');
						buf.append('<div id="'+this.a2Id('Top')+'">');
						buf.append('  <div id="dataHeader">');
												
						buf.append(this.buildTitleHTML(this.data, rightColBuf.toString()));
						
						// DETAILS
						buf.append('    <div id="'+this.a2Id('DiaDetails')+'">');
						buf.append('      <table cellspacing="0" cellpadding="0" border="0" width="100%"><tr><td>');
						buf.append('      <div id="detailsOuterBox">');
						if (this.data.comment != null && this.data.comment != ''){
							buf.append('<p>'+this.data.comment+'</p>'); 
						} 
						else if (this.data.desc != null && this.data.desc != ''){
							buf.append('<p>'+this.data.desc+'</p>'); 
						}   
						else{
							buf.append('<p>No description exists for this diagram.</p>'); 
						}               
                        buf.append(this.buildLinksHTML(this.data));
                        buf.append(this.buildOwnershipHTML(this.data));              
                        buf.append(this.buildRisksHTML(this.data));           
                        buf.append(this.buildRequirementsHTML(this.data)); 
                        buf.append(this.buildStandardsHTML(this.data)); 
                        buf.append(this.buildSuppliersHTML(this.data)); 
                        buf.append(this.buildInputsHTML(this.data)); 
                        buf.append(this.buildOutputsHTML(this.data)); 
                        buf.append(this.buildCustomersHTML(this.data)); 
                        buf.append(this.buildAssignedPersonnelHTML(this.data)); 
                        buf.append(this.buildPerformedByHTML(this.data));     
                        buf.append(this.buildRelatedProcessMapsHTML(this.data));     
                        buf.append(this.buildNestedDocumentsHTML(this.data));   
                        buf.append(this.buildNestedActivitiesHTML(this.data));   
                        buf.append(this.buildFinancialStatementHTML(this.data)); 
                        buf.append(this.buildTestingOwnerHTML(this.data));  
                        buf.append(this.buildTestingContactsHTML(this.data));  
                        buf.append(this.buildTestResultsHTML(this.data));  
                        buf.append(this.buildSupportingDocumentationHTML(this.data));  
                        buf.append(this.buildApprovalListHTML(this.data));  
                        buf.append(this.buildDistributionListHTML(this.data)); 
                        buf.append(this.buildSupervisorHTML(this.data));    
                        buf.append(this.buildAssignedToHTML(this.data));   
                        buf.append(this.buildDirectReportsHTML(this.data));   
                        buf.append(this.buildDirectResponsibilitiesHTML(this.data));            
                        buf.append('      </div>');
						buf.append('      </td></tr></table>');
						buf.append('      <hr>');
						buf.append('    </div>');
						
						buf.append('  </div>');
						buf.append('</div>');
						buf.append('  <td><img src="'+this.pixelImgSrc+'" width="10px"></td>');
						buf.append('</td></tr>');
						buf.append('</table>');
						
						// BOTTOM
						buf.append('<div id="'+this.a2Id('Bottom')+'"></div>'); 
                                   
                        new Insertion.Top(this.element, buf.toString());           
                        Element.hide(this.a2Id('DiaDetails'));            
                        
                        $(this.a2Id('Bottom')).setStyle({
                        							overflow: 'hidden',
                        							height: '100%',
                        							width: '100%'
                        							});
                        							
						if ($(this.a2Id('ToggleDiaDetailsLink')) != null){
							$(this.a2Id('ToggleDiaDetailsLink')).pw = this;	
						}
						this.setPwOnClass(this.a2Id('MoreDetailsLink'));												
					},
                     
initCookie:        	 function()
                     {                        
                        this.cookieUtil = new CookieUtil('synmaps');
                        this.cookieUtil.debug = this.debug;
                        
                        this.cookie = this.cookieUtil.getObj();
                        if(this.cookie == null){
                        	this.setDetailMode(2);
                        }else{
                        	if(this.getCookie().detailWindowOpen){
                        		this.showDetailsWindow();
                        	}
                        	this.updateDetailModeHTML(); 
                        }
                     }, 
                   
initDragBox:         function(){                        
                        
                        var buf = new StringBuffer();                        
						buf.append('<div id="'+this.a2Id('dragBox')+'"><div id="'+this.a2Id('dragImgBox')+'">');
						buf.append('<img id="'+this.a2Id('dragImg')+'" src="'+this.imgSrc+'">');
						buf.append('</div></div>');
                        
                        new Insertion.Bottom(this.a2Id('Bottom'), buf.toString());
                        
                        this.dragable = new Draggable(this.a2Id('dragBox'));
                        this.dragable.options.change = this.constrainDraggable;
                        this.dragable.options.starteffect = Prototype.emptyFunction;
                        this.dragable.options.endeffect = Prototype.emptyFunction;
                        this.dragable.pw = this;
                                             
                        this.dragable.element.setStyle({
                        				position: 'relative',
                        				zIndex:   '0',
                        				cursor:   'move',
                        				left:     '0px',
                        				top:      '5px',
                        				margin:   '10px'                        				
                        				}); 
                        				
						//$(this.a2Id('dragImg')).setStyle({border:   'solid #996600 2px'});                        				                                               
                     },
      
initHotSpots:        function()
                     {       
                     	initHs = null;
                     	initElUri = this.diaUuid;
                     
                     	// see if the hash has a sel property, to pre select this element
                     	h = this.getLocationHash();
                     	if(h && h.sel){
                     		initElUri = h.sel;
                     	}
                     	  
                        for(i=0; i<this.hotSpots.length; i++){
                           this.hotSpots[i].load();
                           
                           //this.debug.log('initHotSpots:      --> "' + this.hotSpots[i].id +'"');
                           
                           // Does this hotspot match our diagram uuid
                           if(this.hotSpots[i].id == initElUri){
                           		initHs = this.hotSpots[i];		
                           }
                        }

                        try {
                        	///if(initHs != null && this.getCookie().detailWindowOpen){
                        	if(initHs != null){
                        		// initially select our diagram hot spot, if the detailWindow is open
                        		this.debug.log('Initially selecting hotspot: ' + initHs.id);
                        		initHs.select();
                        	}else{
                        		this.debug.log('Could not find hotspot with id: ' + initElUri + ' to initially select');
                        		this.hideDetailsWindow();
                        	}
          				}
          				catch (e) {this.debug.log('initHotSpots() Error: '+ e);}
          				
          				if(this.getCookie().decoratorsOn != undefined){
          					this.toggleDecorators(this.getCookie().decoratorsOn);
          				}else{
          					this.toggleDecorators(false);
          				}
          				
                     },
                     
initOverlays:        function()
                     {       
                     	var buf = new StringBuffer();
                     	buf.append('<div id="overlayOuterBox">');  
                     	  
                        for(i=0; i<this.overlays.length; i++){
                           n = this.overlays[i].name;
                           u = this.overlays[i].url;
                                                      
                           buf.append('<a id="'+n+'_overlay_link" href="#" onclick="javascript:this.pw.showOverlayWindow(\''+u+'\');return false;">');
                           buf.append(n);
                           buf.append('</a> &nbsp;|&nbsp; ');                           
                        }
                        buf.append('</div>');
                        
                        try{
	                        Element.update($(this.overlayLinkLocationId), buf.toString()); 	
	                        
	                        for(i=0; i<this.overlays.length; i++){
	                           n = this.overlays[i].name;                                 
	                           $(n+'_overlay_link').pw = this;                         
	                        }
                        }    
	                    catch (e) {this.debug.log('initOverlays() Error: '+ e);}    
                     },                     

initZoomer:        	 function()
                     {                
                     	var dynImgUrlFunc = function(zoomFactor){
                     							return this.imgUrlPrefix + zoomFactor;
                     						}.bind(this);
                       
						var zoomerOpts = {useDynamicImage: true, dynamicImageUrlFunction: dynImgUrlFunc};													 
                     
                        this.zoomer = new ImageZoomer(this.a2Id('dragImg'), this.imgWidth, this.imgHeight, zoomerOpts);
                        this.zoomer.debug = this.debug;    
                     }, 

initZoomLevel:    	 function()
                     {                       
                        // see if the hash has a zoom property, to pre zoom the map
                     	h = this.getLocationHash();
                     	if(h && h.zoom && h.zoom != 0){
                     		maxInitZoomLevel = 4;
                     		minInitZoomLevel = -7;
                     		initZoom = h.zoom;
                     		initZoomLevel = h.zoom;
                     		initZoomIn = true;
                     		
                     		if(initZoom < minInitZoomLevel){
                     			initZoom = minInitZoomLevel;
                     		}
                     		
                     		if(initZoom > maxInitZoomLevel){
                     			initZoom = maxInitZoomLevel;
                     		}
                     		
                     		if(initZoom < 0){
                     			initZoomIn = false;
                     			initZoomLevel = (initZoom + 1);                     			
                     		}else{
                     			initZoomLevel = (initZoom - 1);
                     		}
                     		
                     		this.zoomer.level = initZoomLevel;
                     		for(i=0; i<this.hotSpots.length; i++){
                           		this.hotSpots[i].zoomer.level = initZoomLevel;                           
                        	}
                     		
                        	if(initZoomIn){
                        		this.zoomIn();
                        	}
                        	else{
								this.zoomOut();
							}	    
                     	}
                     
                     },
                     
initWinButtons:    	 function()
                     {                        
                        clssPre = this.win.options.className;                        
                        printClass = clssPre + '_synthis_button ' + clssPre + '_print ' + this.a2Id('setPw');
                        zInClass = clssPre + '_synthis_button ' + clssPre + '_zoomin ' + this.a2Id('setPw');
                        zOutClass = clssPre + '_synthis_button ' + clssPre + '_zoomout ' + this.a2Id('setPw');
                        zResClass = clssPre + '_synthis_button ' + clssPre + '_zoomrestore ' + this.a2Id('setPw');
                        //decClass = clssPre + '_synthis_button ' + clssPre + '_decoratorbutton ' + this.a2Id('setPw');
                        decClass_owner = clssPre + '_synthis_button ' + clssPre + '_decoratorbutton_owner ' + this.a2Id('setPw');
                        decClass_link = clssPre + '_synthis_button ' + clssPre + '_decoratorbutton_link ' + this.a2Id('setPw');
                        decClass_require = clssPre + '_synthis_button ' + clssPre + '_decoratorbutton_require ' + this.a2Id('setPw');
                        maximizeClass = clssPre + '_synthis_button ' + clssPre + '_diamaximize ' + this.a2Id('setPw');
                        
                        var buf = new StringBuffer();						
                        buf.append('<div title="Print Diagram" class="'+printClass+'" id="'+this.a2Id('print')+'" onmouseup="this.pw.print()"> </div>');
						buf.append('<div title="Zoom In" class="'+zInClass+'" id="'+this.a2Id('zoomin')+'" onmouseup="this.pw.zoomIn()"> </div>');
						buf.append('<div title="Actual Size" class="'+zResClass+'" id="'+this.a2Id('zoomrestore')+'" onmouseup="this.pw.zoomRestore()"> </div>');
						buf.append('<div title="Zoom Out" class="'+zOutClass+'" id="'+this.a2Id('zoomout')+'" onmouseup="this.pw.zoomOut()"> </div>');
						//buf.append('<div title="Show/Hide Decorators" class="'+decClass+'" id="'+this.a2Id('decoratorbutton')+'" onmouseup="this.pw.toggleDecorators()"> </div>');
						buf.append('<div title="Show/Hide Ownership" class="'+decClass_owner+'" id="'+this.a2Id('decoratorbutton_owner')+'" onmouseup="this.pw.toggleDecorators(undefined, \'owner\')"> </div>');
						buf.append('<div title="Show/Hide Linked Resources" class="'+decClass_link+'" id="'+this.a2Id('decoratorbutton_link')+'" onmouseup="this.pw.toggleDecorators(undefined, \'link\')"> </div>');
						buf.append('<div title="Show/Hide Requirements" class="'+decClass_require+'" id="'+this.a2Id('decoratorbutton_require')+'" onmouseup="this.pw.toggleDecorators(undefined, \'require\')"> </div>');
						buf.append('<div title="Maximize" class="'+maximizeClass+'" id="'+this.a2Id('diamaximize')+'" onmouseup="this.pw.toggleWindowMaximize()"> </div>');                              
                                                
                        new Insertion.Top(this.win.element, buf.toString());
                        
                        this.setPwOnClass(this.a2Id('setPw'));                        
                     },                     

onResize:			 function(){
						this.debug.log("ProcessWebsite.onResize()");
						
						if(!this.maximized) {
						
							page = WindowUtilities.getPageSize();
							dims = this.getWindowDimensions();
							
							this.win.setSize(dims.width,dims.height);
							
							if(this.detailsWin != null && this.detailsWin.isVisible()){
								this.detailsWin.setSize(this.detailsWinWidth, dims.height);
								this.detailsWin.setLocation(this.winTop,this.winLeft);
								this.getCookie().detailWindowOpen = true;
							}else{
								this.getCookie().detailWindowOpen = false;
							}
							
							if(this.overlayWin != null){							
								overlayPos = this.getOverlayWinPosition();
								this.overlayWin.setSize(overlayPos.width, overlayPos.height);
								this.overlayWin.setLocation(overlayPos.top,overlayPos.left);							
							}
							
							// save details window open state in cookie
	                        this.saveCookie(); 
	                                               		
                        }else{
                        	
                        	// maximize is true
							var page = WindowUtilities.getPageSize();
							
							var theWidth = page.windowWidth;
							
							var newWidth = theWidth - (this.offsetWidth / 2);
							
							var theHeight = page.windowHeight;
							
							var newHeight = this.imgHeight + 80;
							if(newHeight < (theHeight - 80)){
								newHeight = (theHeight - 80);
								}
								else if (!isIE){
									// must subtract width of Firefox scrollbar
									newWidth = newWidth - 16;
							}
							
							//this.debug.log('toggleWindowMaximize - dim 1:      ' + isIE + ', ' + Element.getHeight($$('body')[0]));
							//this.debug.log('toggleWindowMaximize - dim 2:      ' + page.windowWidth + ', ' + page.windowHeight);
							//this.debug.log('toggleWindowMaximize - used dims:  ' + theWidth + ', ' + theHeight);
							//this.debug.log('toggleWindowMaximize - new dims:   ' + newWidth + ', '+ newHeight);
							//this.debug.log('toggleWindowMaximize - img dims:   ' + this.imgWidth + ', ' + this.imgHeight);
							
							this.win.setSize(newWidth,newHeight);
							this.win.setLocation(10,2);
                        }										
					 },

toggleWinTop:      	 function()
                     {                       	
                     	$(this.a2Id('ToggleDiaDetailsLink')).blur();
                     	winTopEl = $(this.a2Id('DiaDetails')); 
                     	imgEl = $(this.a2Id('ToggleDiaDetailsImg'));
                     	                    	
                     	Element.toggle(winTopEl);                        
                        
                        if(Element.visible(winTopEl)){
                        	imgEl.src = this.collapseImgSrc;
                        }else{
                        	imgEl.src = this.expandImgSrc;
                        }
                     },

getWindowDimensions: function(){	
						// WindowUtilities comes from window.js
						var page = WindowUtilities.getPageSize();
						
						var theWidth  = page.windowWidth - this.offsetWidth;
						var theHeight = page.windowHeight - this.offsetHeight;
						
						if(this.detailsWin != null && this.detailsWin.isVisible()){
							extraWidth = this.detailsWinWidth + this.detailsWinPadding;							
							theWidth = theWidth - extraWidth;
							this.win.setLocation(this.winTop,this.winLeft + extraWidth);
						}
						else if(this.win != null){							
							this.win.setLocation(this.winTop,this.winLeft);
						}
						
						this.debug.log('ProcessWebsite.getWindowDimensions() ' + theWidth + ' x ' + theHeight);
						
						return {width: theWidth, height: theHeight};
					 },
					 
getPositionInfo:	function(){
						d = this.dragable.currentDelta();
                        l = d[0];
                        t = d[1];
						zPer = this.zoomer.getZoomPercentage();
						
						// compute constrain padding
						maxConstrainPad = 300;                      
                        constrainPad = maxConstrainPad * zPer;
                        if(constrainPad > maxConstrainPad){
                        	constrainPad = maxConstrainPad;
                        }
                        
                        smallerDim = this.win.width;
                        if(this.win.height < smallerDim){
                        	smallerDim = this.win.height;
                        }
                        
                        if(constrainPad > (smallerDim/2)){
                        	constrainPad = smallerDim/2;
                        }
						
						imgDims = Element.getDimensions(this.a2Id('dragImg'));
						
						smallerDim = imgDims.width;
                        if(imgDims.height < smallerDim){
                        	smallerDim = imgDims.height;
                        }
                        
                        if(constrainPad > (smallerDim/2)){
                        	constrainPad = smallerDim/2;
                        }   
                        
                        // this is the smallest the pad can be
                        if(constrainPad < 50){
                        	constrainPad = 50;
                        }
						
                        minLeft = -1 * (imgDims.width - constrainPad);
                        maxLeft = (this.win.width - constrainPad);
                        
                        minTop = -1 * (imgDims.height - constrainPad + 25);
                        maxTop = (this.win.height - constrainPad - 25);
						
						// this is debug info
						if(this.debug.DEBUG){
	                        dStr = '(LEFT: ' + l + '  TOP:' + t + ')<br>';
	                        dStr = dStr + ' win width:' + this.win.width;
	                        dStr = dStr + ' win height:' + this.win.height + '<br>';
	                        dStr = dStr + ' minLeft:' + minLeft;
	                        dStr = dStr + ' maxLeft:' + maxLeft + '<br>';
	                        dStr = dStr + ' minTop:' + minTop;
	                        dStr = dStr + ' maxTop:' + maxTop + '<br>';
	                        dStr = dStr + ' img width:' + imgDims.width;
	                        dStr = dStr + ' img height:' + imgDims.height + '<br>';
	                        dStr = dStr + ' constrainPad:' + constrainPad;
	                        dStr = dStr + ' zoom %:' + zPer;
	                        this.debug.replace(dStr);
                        }
						
						return {
								minLeft: minLeft,
								maxLeft: maxLeft,
								minTop: minTop,
								maxTop: maxTop,
								l: l,
								t: t,
								zPer: zPer,
								imgW: imgDims.width,
								imgH: imgDims.height,
								constrainPad: constrainPad
								};						
					},	

constrainDraggable:  function(dragable)
                     {                        
                        /* This is used by initDragBox()  (The draggable change event handler) */
                        var style = dragable.element.style;
                        var el = dragable.element;    
                        var pw = dragable.pw;
                                  
                        // This is to close a popup on drag
                        if(pw.selectedHotSpot != null && pw.selectedHotSpot.popUp != null){
                        	pw.selectedHotSpot.popUp.hide();
                        }          
                        
                        pos = pw.getPositionInfo();
                        
                        if(pos.l < pos.minLeft) {el.setStyle({left: pos.minLeft + 'px'});}
                        if(pos.l > pos.maxLeft) {el.setStyle({left: pos.maxLeft + 'px'});}
                        if(pos.t < pos.minTop)  {el.setStyle({top: pos.minTop + 'px'});}
                        if(pos.t > pos.maxTop)  {el.setStyle({top: pos.maxTop + 'px'});}
                     },
                     
addHotSpot:          function(id, left, top, data)
                     {
                        hs = new HotSpot(this, id, left, top, data);
                        this.hotSpots.push(hs);                        
                     },

addOverlay:          function(name, url)
                     {
                        overlay = {};
                        overlay.name = name;
                        overlay.url = url;
                        this.s.push(overlay);                        
                     },

showOverlayWindow:   function(url)
                     {
                     	this.debug.log('showOverlayWindow() url: '+ url);
                     	
                     	overlayPos = this.getOverlayWinPosition();
                     	
                     	if(this.overlayWin == null){
                     		options = Object.extend(new DefaultWinOptions(),
                                 {
                                    width: overlayPos.width,
                                    height: overlayPos.height,
                                    closable: true,
                              		minimizable: false,
                              		maximizable: false,
                              		url: url,
									opacity: .999999
                                 }); 
                                 
                            this.overlayWin = new Window('pwOverlayWindow', options); 
                            this.overlayWin.pw = this;                         		
                     	}
                     	  
                     	try{
	                     	this.overlayWin.getContent().src = url; 
	                    }    
	                    catch (e) {
	                    	this.debug.log('showOverlayWindow() Error: '+ e);
	                    }  	
	                     	                    	
                     	this.overlayWin.options.url = url;
                     	          
                     	this.overlayWin.getContent().setStyle({
                        					overflow: 	'auto',
                        					border:	    '0px none white'                        					                        					                        					
                        					});  
                     	
                     	this.overlayWin.setLocation(overlayPos.top, overlayPos.left);
                     	
                     	// this is here to make the window come to the front
                     	// I think this is due to a bug in the the window.js
                     	Windows.focusedWindow = null;
                        this.overlayWin.toFront();
                        this.overlayWin.show();                                                                      
                     },

getOverlayWinPosition: function(){
					
						page = WindowUtilities.getPageSize();
						dims = this.getWindowDimensions();
						
						returnObj = {};
						returnObj.width = page.windowWidth * .7;
						returnObj.height = dims.height;
						returnObj.left = ((page.windowWidth - returnObj.width)/ 2) - 15;
						returnObj.top = this.winTop - 30;
	
						//this.debug.log('getOverlayWinPosition() - '+showObj(returnObj, ['width','height','top','left']));
	
						return returnObj;
					 },
                     
showDetailsWindow:   function()
                     {
                     	if(this.detailsWin == null){
                     		
                     		dims = this.getWindowDimensions();
                        	
                        	options = Object.extend(new DefaultWinOptions(),
                                 {
                                    width:280,
                                    height:dims.height,
                                    closable: true,
                              		minimizable: false,
                              		maximizable: false
                                 });  
                            
                            this.detailsWin = new Window('pwDetailsWindow', options); 
                            this.detailsWin.getContent().setStyle({overflow: 'auto'});
                            this.detailsWin.pw = this;
                     	    
                     	    winObserver =	{
	                              	checkWin:	function(win)
	                            				{
	                            					return (win != null && win.element != null && win.element.id == 'pwDetailsWindow');
	                            				},	                              	
	                            	onHide:		function(eventName,win)
	                            				{
	                            					if(this.checkWin(win) && win.pw != null){
                            							win.pw.onResize();
	                            					}
	                            				}
	                            	};
							Windows.addObserver(winObserver); 							                            							                        							
                     	}
                           
                        this.detailsWin.setLocation(this.winTop,this.winLeft);
                        this.detailsWin.toFront();
                        this.detailsWin.show(); 
                           
                        this.onResize();                        
                     },
                     
hideDetailsWindow:   function()
                     {
                     	if(this.detailsWin != null){
                     		this.detailsWin.hide();
                     	}
                     },
                     
updateDetailsWindow: function(data)
                     {                     	
                        if(this.detailsWin == null || !this.detailsWin.isVisible()){
                        	this.showDetailsWindow();
                        }          
                              
                        var winEl = this.detailsWin.getContent();
                        Element.update(winEl, this.buildDetailsHTML(data));
                        
                        //this.detailsWin.setTitle('<b>'+data.name+'</b>');
                        this.detailsWin.setTitle('&nbsp;'); 
                        
                        this.setPwOnClass(this.a2Id('MoreDetailsLink'));                        
                     }, 

buildTitleHTML:		function(data, rightColHtml){			
						var buf = new StringBuffer();
						
						buf.append('<table cellspacing="0" cellpadding="0" border="0" width="100%">');
						buf.append('<tr height="20">');
						buf.append('<td>');
						if( data.status == 'Future State' ){
							buf.append('	<table border="0"><tr><td valign="top" nowrap><img src="'+data.icon+'">&nbsp;</td><td valign="top" style="padding-top:2px"><b>'+data.name+'</b> - FUTURE STATE</td></tr></table>');
						}else{
							buf.append('	<table border="0"><tr><td valign="top" nowrap><img src="'+data.icon+'">&nbsp;</td><td valign="top" style="padding-top:2px"><b>'+data.name+'</b></td></tr></table>');
						}
						buf.append('</td>');
						buf.append('<td align="right">');
						buf.append(rightColHtml || '&nbsp;');
						buf.append('</td></tr>');						
						buf.append('<tr><td colspan="2">');
						buf.append('<hr>');
						buf.append('</td></tr>');
						buf.append('</table>');
						
						return buf.toString();						
					},
					
buildLinksHTML:		function(data){			
						var buf = new StringBuffer();
						
						if( data.processMapUri != null && data.processMapUri != '' ){
                        	buf.append('<div id="dataSubTitle">Process Narrative</div>');
                        	buf.append('<table width="100%" cellpadding="0" cellspacing="4" border="0">');
                        	
                       		buf.append('<tr>');
                       		buf.append('<td align="left" valign="top" nowrap>');
                       		buf.append('<img border="0" alt="" src="'+this.htmlDocumentImgSrc+'">');
                       		buf.append('<br><img border="0" alt="" height="0" width="24" src="'+this.pixelImgSrc+'">');
                       		buf.append('</td>');
                       		buf.append('<td width="100%" valign="top" align="left">');
                       		
                       		buf.append('<a href="../../../processnarrative?processmap='+data.processMapUri+'#'+data.processMapUri+'-Diagram" target="_blank">'+data.name+'</a>');
							
                       		buf.append('</td>');
                       		buf.append('</tr>');
	                       	
                        	buf.append('</table>');
                        }
                        
						if( data.hyperlink != null && data.hyperlink != '' ){
                        	buf.append('<div id="dataSubTitle">Hyperlink</div>');
                        	buf.append('<table width="100%" cellpadding="0" cellspacing="4" border="0">');
							
	                       	if(data.hyperlink != null && data.hyperlink != '') {
	                       		buf.append('<tr>');
	                       		buf.append('<td align="left" valign="top" nowrap>');
	                       		buf.append('<img border="0" alt="" src="'+data.icon+'">');
	                       		buf.append('<br><img border="0" alt="" height="0" width="24" src="'+this.pixelImgSrc+'">');
	                       		buf.append('</td>');
	                       		buf.append('<td width="100%" valign="top" align="left">');
	                       		
	                       		buf.append('<a href="'+data.hyperlink+'" target="'+data.name+'">');
	                       		
	                       		buf.append(data.name);
	                       		buf.append('</a>&nbsp;');
	                       		buf.append('</td>');
	                       		buf.append('</tr>');
	                       	}
	                       	
                        	buf.append('</table>');
                        }
						
						if( data.links != undefined && data.links.length > 0 ){
                        	buf.append('<div id="dataSubTitle">Linked Resources</div>');
                        	buf.append('<table width="100%" cellpadding="0" cellspacing="4" border="0">');
	                       
                        	for(var i=0; i<data.links.length; i++) {
                        		link = data.links[i];
                        		       
                        		buf.append('<tr><td align="left" valign="top" nowrap>');
                        		buf.append('<img border="0" alt="" src="'+link.img+'">');
                        		buf.append('<br><img border="0" alt="" height="0" width="24" src="'+this.pixelImgSrc+'">');
                        		buf.append('</td>');
                        		buf.append('<td width="100%" valign="top" align="left">');
                        		
                        		if(link.hyperlink != null && link.hyperlink != ''){
                        			buf.append('<a href="'+link.hyperlink+'" target="'+link.name+'" title="'+link.desc+'">'+link.name+'</a>&nbsp;');
                        		}
                        		else{
                        			detailUrl = 'element?e=' + link.uri; 
                        			buf.append('<a class="'+this.a2Id('MoreDetailsLink')+'" href="#" onclick="javascript:this.pw.showOverlayWindow(\''+detailUrl+'\');return false;">'+link.name+'</a>&nbsp;');
                        		}
                        		
                        		buf.append('</td>');
                        		buf.append('</tr>');
                        	}
                        	
                        	buf.append('</table>');
                        }
						
						return buf.toString();						
					},					

buildOwnershipHTML:	function(data){			
						return this.buildGenericHTMLList(data.ownerList, 'Owner');												
					},   	

buildRisksHTML:	function(data){			
						return this.buildGenericHTMLList(data.risksList, 'Risks');												
					},

buildRequirementsHTML:	function(data){			
						return this.buildGenericHTMLList(data.requirementsList, 'Requirements');												
					},			

buildStandardsHTML:	function(data){			
						return this.buildGenericHTMLList(data.standardsList, 'Standards');
					},		

buildSuppliersHTML:	function(data){			
						return this.buildGenericHTMLList(data.suppliersList, 'Suppliers');
					},		

buildInputsHTML:	function(data){			
						return this.buildGenericHTMLList(data.inputsList, 'Inputs');
					},		

buildOutputsHTML:	function(data){			
						return this.buildGenericHTMLList(data.outputsList, 'Outputs');
					},		

buildCustomersHTML:	function(data){			
						return this.buildGenericHTMLList(data.customersList, 'Customers');
					},	

buildAssignedPersonnelHTML:	function(data){			
						return this.buildGenericHTMLList(data.assignedPersonnelList, 'Assigned Personnel');												
					}, 

buildPerformedByHTML:	function(data){			
						return this.buildGenericHTMLList(data.performedByList, 'Performed By');					
					},		

buildRelatedProcessMapsHTML:	function(data){			
						var buf = new StringBuffer();
						
						if( data.relatedProcessMaps != undefined && data.relatedProcessMaps.length > 0 ){
                        	buf.append('<div id="dataSubTitle">Process Maps</div>');
                        	buf.append('<table width="100%" cellpadding="0" cellspacing="4" border="0">');
	                       
                        	for(var i=0; i<data.relatedProcessMaps.length; i++) {
                        		processMap = data.relatedProcessMaps[i];
                        		
                        		buf.append('<tr><td align="left" valign="top" nowrap>');
                        		buf.append('<img border="0" alt="" src="'+processMap.img+'">');
                        		buf.append('<br><img border="0" alt="" height="0" width="24" src="'+this.pixelImgSrc+'">');
                        		buf.append('</td>');
                        		buf.append('<td width="100%" valign="top" align="left">');
                        		
                        		detailUrl = 'map?e=' + processMap.uri; 
                        		buf.append('<a href="'+detailUrl+'">'+processMap.name+'</a>&nbsp;');
                        		
                        		buf.append('</td>');
                        		buf.append('</tr>');
                        	}
                        	
                        	buf.append('</table>');
                        }
						
						return buf.toString();						
					},		

buildNestedDocumentsHTML:	function(data){			
						return this.buildGenericHTMLList(data.nestedDocuments, 'Nested Documents');					
					},

buildNestedActivitiesHTML:	function(data){			
						return this.buildGenericHTMLList(data.nestedActivities, 'Nested Activities');					
					},

buildFinancialStatementHTML:	function(data){			
						return this.buildGenericHTMLList(data.financialStatement, 'Financial Statement');					
					},

buildTestingOwnerHTML:	function(data){			
						return this.buildGenericHTMLList(data.testingOwner, 'Testing Owner');					
					},

buildTestingContactsHTML:	function(data){			
						return this.buildGenericHTMLList(data.testingContacts, 'Testing Contacts');					
					},

buildTestResultsHTML:	function(data){			
						return this.buildGenericHTMLList(data.testResults, 'Test Results');					
					},

buildSupportingDocumentationHTML:	function(data){			
						return this.buildGenericHTMLList(data.supportingDocumentation, 'Supporting Documentation');					
					},

buildApprovalListHTML:	function(data){			
						return this.buildGenericHTMLList(data.approvalList, 'Approval List');					
					},

buildDistributionListHTML:	function(data){			
						return this.buildGenericHTMLList(data.distributionList, 'Distribution List');					
					},				

buildSupervisorHTML:	function(data){			
						return this.buildGenericHTMLList(data.supervisorList, 'Supervisor');												
					},

buildAssignedToHTML:	function(data){			
						return this.buildGenericHTMLList(data.assignedTo, 'Roles/Groups');					
					},

buildDirectReportsHTML:	function(data){			
						return this.buildGenericHTMLList(data.directReports, 'Direct Reports');					
					},

buildDirectResponsibilitiesHTML:	function(data){			
						return this.buildGenericHTMLList(data.directResponsibilities, 'Direct Responsibilities');					
					},
					
buildGenericHTMLList:	function(theList, theTitle){			
						var buf = new StringBuffer();
						
						if(theList != undefined && theList.length > 0){
                        	buf.append('<div id="dataSubTitle">'+theTitle+'</div>');
                        	buf.append('<table width="100%" cellpadding="0" cellspacing="4" border="0">');
                        	for(var i=0; i<theList.length; i++) {
                        		anObj = theList[i];
                        		       
                        		buf.append('<tr><td align="left" valign="top" nowrap>');
                        		buf.append('<img border="0" alt="" src="'+anObj.img+'">');
                        		buf.append('<br><img border="0" alt="" height="0" width="24" src="'+this.pixelImgSrc+'">');
                        		buf.append('</td>');
                        		buf.append('<td width="100%" valign="top" align="left">');
                        		detailUrl = 'element?e=' + anObj.uri; 
                        		buf.append('<a class="'+this.a2Id('MoreDetailsLink')+'" href="#" onclick="javascript:this.pw.showOverlayWindow(\''+detailUrl+'\');return false;">'+anObj.name+'</a>');
                        		//buf.append(anObj.name);
                        		buf.append('&nbsp;');
                        		buf.append('</td>');
                        		buf.append('</tr>');
                        	}
                        	buf.append('</table>');
                        }
						
						return buf.toString();						
					},					

buildMoreInfoLinkHTML: function(data)
                     {
                     	var buf = new StringBuffer();
                        detailUrl = 'element?e=' + data.id; 
                        buf.append('<a class="'+this.a2Id('MoreDetailsLink')+'" href="#" onclick="javascript:this.pw.showOverlayWindow(\''+detailUrl+'\');return false;">');
                        buf.append('More Info >></a>');
                        return buf.toString();
                     },
                     
buildPopUpDetailsHTML:    function(data)
                     {                     	
                     	var buf = new StringBuffer();
						buf.append('<div id="detailsOuterBox" width="100%">');
						buf.append(' <table cellspacing="10" cellpadding="0" border="0" width="100%"><tr><td>');
						buf.append('  <div id="detailsInnerBox">');
						buf.append(this.buildTitleHTML(data));
						if (data.desc != null && data.desc != ''){
							buf.append('<p>'+data.desc+'</p>');      
						}
						else if (data.comment != null && data.comment != ''){
							buf.append('<p>'+data.comment+'</p>');      
						}
						else{
							buf.append('<p>No description exists for this element.</p>'); 
						}   
						if (data.documentId != null && data.documentId != ''){
							buf.append('<div id="dataSubTitle">Document ID</div>'); 
							buf.append('<p>'+data.documentId+'</p>'); 
						}  
						if (data.recordId != null && data.recordId != ''){
							buf.append('<div id="dataSubTitle">Record ID</div>'); 
							buf.append('<p>'+data.recordId+'</p>'); 
						}  
						if (data.personTitle != null && data.personTitle != ''){
							buf.append('<div id="dataSubTitle">Title</div>'); 
							buf.append('<p>'+data.personTitle+'</p>'); 
						}    
						if (data.department != null && data.department != ''){
							buf.append('<div id="dataSubTitle">Department</div>'); 
							buf.append('<p>'+data.department+'</p>'); 
						}
						if (data.phone != null && data.phone != ''){
							buf.append('<div id="dataSubTitle">Phone</div>'); 
							buf.append('<p>'+data.phone+'</p>'); 
						}
						if (data.fax != null && data.fax != ''){
							buf.append('<div id="dataSubTitle">Fax</div>'); 
							buf.append('<p>'+data.fax+'</p>'); 
						}
						if (data.mobile != null && data.mobile != ''){
							//buf.append('<div id="dataSubTitle">Mobile</div>'); 
							//buf.append('<p>'+data.mobile+'</p>'); 
						}
						if (data.email != null && data.email != ''){
							buf.append('<div id="dataSubTitle">Email</div>'); 
							buf.append('<p><a href="mailto:'+data.email+'">'+data.email+'</a></p>'); 
						}
                        buf.append(this.buildLinksHTML(data));
						if (data.testPlan != null && data.testPlan != ''){
							buf.append('<div id="dataSubTitle">Test Plan</div>'); 
							buf.append('<p>'+data.testPlan+'</p>'); 
						}  
                        buf.append(this.buildOwnershipHTML(data)); 
                        buf.append(this.buildRisksHTML(data));  
                        buf.append(this.buildRequirementsHTML(data));
                        buf.append(this.buildStandardsHTML(data)); 
                        buf.append(this.buildSuppliersHTML(data)); 
                        buf.append(this.buildInputsHTML(data)); 
                        buf.append(this.buildOutputsHTML(data)); 
                        buf.append(this.buildCustomersHTML(data));  
                        buf.append(this.buildAssignedPersonnelHTML(data)); 
                        buf.append(this.buildPerformedByHTML(data)); 
                        buf.append(this.buildRelatedProcessMapsHTML(data)); 
                        buf.append(this.buildNestedDocumentsHTML(data)); 
                        buf.append(this.buildNestedActivitiesHTML(data)); 
                        buf.append(this.buildFinancialStatementHTML(data));
                        buf.append(this.buildTestingOwnerHTML(data));
                        buf.append(this.buildTestingContactsHTML(data));
                        buf.append(this.buildTestResultsHTML(data));
                        buf.append(this.buildSupportingDocumentationHTML(data));
                        buf.append(this.buildApprovalListHTML(data)); 
                        buf.append(this.buildDistributionListHTML(data)); 
                        buf.append(this.buildSupervisorHTML(data));
                        buf.append(this.buildAssignedToHTML(data));
                        buf.append(this.buildDirectReportsHTML(data));
                        buf.append(this.buildDirectResponsibilitiesHTML(data)); 
						if (data.purpose != null && data.purpose != ''){
							buf.append('<div id="dataSubTitle">Purpose</div>'); 
							buf.append('<p>'+data.purpose+'</p>'); 
						}  
						if (data.scope != null && data.scope != ''){
							buf.append('<div id="dataSubTitle">Scope</div>'); 
							buf.append('<p>'+data.scope+'</p>'); 
						}  
						if (data.definitions != null && data.definitions != ''){
							buf.append('<div id="dataSubTitle">Definitions</div>'); 
							buf.append('<p>'+data.definitions+'</p>'); 
						}  
						if (data.responsibilities != null && data.responsibilities != ''){
							buf.append('<div id="dataSubTitle">Responsibilities</div>'); 
							buf.append('<p>'+data.responsibilities+'</p>'); 
						}  
						if (data.procedures != null && data.procedures != ''){
							buf.append('<div id="dataSubTitle">Procedures</div>'); 
							buf.append('<p>'+data.procedures+'</p>'); 
						}  
						if (data.location != null && data.location != ''){
							buf.append('<div id="dataSubTitle">Location</div>'); 
							buf.append('<p>'+data.location+'</p>'); 
						}  
						if (data.disposal != null && data.disposal != ''){
							buf.append('<div id="dataSubTitle">Disposal Instructions</div>'); 
							buf.append('<p>'+data.disposal+'</p>'); 
						}  
                        buf.append('   <div align="right">'); 
                        buf.append(this.buildMoreInfoLinkHTML(data));                                            
                        buf.append('   </div>');
                        buf.append('  </div>');
                        buf.append(' </td></tr></table>');
                        buf.append('</div>');
                        
                        return buf.toString();
                     }, 
                     
buildDetailsHTML:    function(data)
                     {                     	
                     	var buf = new StringBuffer();
						buf.append('<div id="detailsOuterBox">');
						buf.append(' <table cellspacing="10" cellpadding="0" border="0" width="100%"><tr><td>');
						buf.append('  <div id="detailsInnerBox">');
						buf.append(this.buildTitleHTML(data));
						if (data.comment != null && data.comment != ''){
							buf.append('<p>'+data.comment+'</p>');      
						} 
						else if (data.desc != null && data.desc != ''){
							buf.append('<p>'+data.desc+'</p>');      
						}          
						else{
							buf.append('<p>No description exists for this element.</p>'); 
						}     
						if (data.documentId != null && data.documentId != ''){
							buf.append('<div id="dataSubTitle">Document ID</div>'); 
							buf.append('<p>'+data.documentId+'</p>'); 
						}   
						if (data.recordId != null && data.recordId != ''){
							buf.append('<div id="dataSubTitle">Record ID</div>'); 
							buf.append('<p>'+data.recordId+'</p>'); 
						}  
						if (data.personTitle != null && data.personTitle != ''){
							buf.append('<div id="dataSubTitle">Title</div>'); 
							buf.append('<p>'+data.personTitle+'</p>'); 
						}    
						if (data.department != null && data.department != ''){
							buf.append('<div id="dataSubTitle">Department</div>'); 
							buf.append('<p>'+data.department+'</p>'); 
						}   
						if (data.phone != null && data.phone != ''){
							buf.append('<div id="dataSubTitle">Phone</div>'); 
							buf.append('<p>'+data.phone+'</p>'); 
						}
						if (data.fax != null && data.fax != ''){
							buf.append('<div id="dataSubTitle">Fax</div>'); 
							buf.append('<p>'+data.fax+'</p>'); 
						}
						if (data.mobile != null && data.mobile != ''){
							//buf.append('<div id="dataSubTitle">Mobile</div>'); 
							//buf.append('<p>'+data.mobile+'</p>'); 
						}
						if (data.email != null && data.email != ''){
							buf.append('<div id="dataSubTitle">Email</div>'); 
							buf.append('<p><a href="mailto:'+data.email+'">'+data.email+'</a></p>'); 
						}    
                        buf.append(this.buildLinksHTML(data));
						if (data.testPlan != null && data.testPlan != ''){
							buf.append('<div id="dataSubTitle">Test Plan</div>'); 
							buf.append('<p>'+data.testPlan+'</p>'); 
						}  
                        buf.append(this.buildOwnershipHTML(data));
                        buf.append(this.buildRisksHTML(data));  
                        buf.append(this.buildRequirementsHTML(data)); 
                        buf.append(this.buildStandardsHTML(data));
                        buf.append(this.buildSuppliersHTML(data)); 
                        buf.append(this.buildInputsHTML(data)); 
                        buf.append(this.buildOutputsHTML(data)); 
                        buf.append(this.buildCustomersHTML(data)); 
                        buf.append(this.buildAssignedPersonnelHTML(data)); 
                        buf.append(this.buildPerformedByHTML(data)); 
                        buf.append(this.buildRelatedProcessMapsHTML(data)); 
                        buf.append(this.buildNestedDocumentsHTML(data)); 
                        buf.append(this.buildNestedActivitiesHTML(data)); 
                        buf.append(this.buildFinancialStatementHTML(data));
                        buf.append(this.buildTestingOwnerHTML(data));
                        buf.append(this.buildTestingContactsHTML(data));
                        buf.append(this.buildTestResultsHTML(data));
                        buf.append(this.buildSupportingDocumentationHTML(data));
                        buf.append(this.buildApprovalListHTML(data)); 
                        buf.append(this.buildDistributionListHTML(data));  
                        buf.append(this.buildSupervisorHTML(data)); 
                        buf.append(this.buildAssignedToHTML(data)); 
                        buf.append(this.buildDirectReportsHTML(data));
                        buf.append(this.buildDirectResponsibilitiesHTML(data)); 
						if (data.purpose != null && data.purpose != ''){
							buf.append('<div id="dataSubTitle">Purpose</div>'); 
							buf.append('<p>'+data.purpose+'</p>'); 
						}  
						if (data.scope != null && data.scope != ''){
							buf.append('<div id="dataSubTitle">Scope</div>'); 
							buf.append('<p>'+data.scope+'</p>'); 
						}  
						if (data.definitions != null && data.definitions != ''){
							buf.append('<div id="dataSubTitle">Definitions</div>'); 
							buf.append('<p>'+data.definitions+'</p>'); 
						}  
						if (data.responsibilities != null && data.responsibilities != ''){
							buf.append('<div id="dataSubTitle">Responsibilities</div>'); 
							buf.append('<p>'+data.responsibilities+'</p>'); 
						}  
						if (data.procedures != null && data.procedures != ''){
							buf.append('<div id="dataSubTitle">Procedures</div>'); 
							buf.append('<p>'+data.procedures+'</p>'); 
						}  
						if (data.location != null && data.location != ''){
							buf.append('<div id="dataSubTitle">Location</div>'); 
							buf.append('<p>'+data.location+'</p>'); 
						}  
						if (data.disposal != null && data.disposal != ''){
							buf.append('<div id="dataSubTitle">Disposal Instructions</div>'); 
							buf.append('<p>'+data.disposal+'</p>'); 
						}  
                        buf.append('   <div align="right">'); 
                        buf.append(this.buildMoreInfoLinkHTML(data));                                            
                        buf.append('   </div>');
                        buf.append('  </div>');
                        buf.append(' </td></tr></table>');
                        buf.append('</div>');
                        
                        return buf.toString();
                     },                         
                     
setDetailMode:       function(mode)
                     {       
                        this.getCookie().detailMode = mode;
                        this.saveCookie();   
                        
                        if(mode == 1){
                        	if(this.selectedHotSpot != null){
                        		this.selectedHotSpot.select();
                        	}
                        	this.showDetailsWindow();
                        }
                        if(mode == 2){
                        	this.hideDetailsWindow();
                        }
                        
                        this.updateDetailModeHTML();                      
                     },
                     
getDetailMode:       function()
                     {                        
                        return this.getCookie().detailMode;
                     },                                                             
     
updateDetailModeHTML:function()
                     {  
                     	mode = this.getDetailMode();
                        
                        var buf = new StringBuffer();
						buf.append('<div id="detailsOuterBox">');
                        
                        if(mode == 1){
                        	buf.append('<b>Window Mode</b> &nbsp;|&nbsp; ');
                        	buf.append('<a id="'+this.detailModeId+'_link" href="#" onclick="javascript:this.pw.setDetailMode(2);return false;">');
                        	buf.append('Popup Mode</a>');
                        }
                        
                        if(mode == 2){
                        	buf.append('<a id="'+this.detailModeId+'_link" href="#" onclick="javascript:this.pw.setDetailMode(1);return false;">');
                        	buf.append('Window Mode</a> &nbsp;|&nbsp; <b>Popup Mode</b>');
                        }

                     	buf.append('</div>');

                        Element.update($(this.detailModeId), buf.toString()); 
                     	//$(this.detailModeId+'_link').setStyle({color: '#7F8D96'});                     	
                     	$(this.detailModeId+'_link').pw = this;
                     },

toggleDecorators:    function(overrideOn, toggleClassSuffix){
						
						if(this.zoomer != undefined && this.zoomer.getZoomPercentage() != 1){
							return;
						}
						
						if(!toggleClassSuffix){
							// default decorator
							toggleClassSuffix = 'link';
						}
						
						if(overrideOn != undefined){
							decOn = overrideOn;
						}
						else if(this.getCookie().decoratorSuffix && this.getCookie().decoratorSuffix != toggleClassSuffix){
							decOn = true;
						}
						else{
							decOn = !this.getCookie().decoratorsOn;
						}
	
						for(i=0; i<this.hotSpots.length; i++){
                           this.hotSpots[i].toggleDecorators(decOn, toggleClassSuffix);   
                           
                           //this.hotSpots[i].toggleDecorators2(decOn, forOwner, forLink);
                                                   
                        }
							
						this.getCookie().decoratorsOn = decOn;
						this.getCookie().decoratorSuffix = toggleClassSuffix;	
						this.saveCookie();						
					 },
					 
toggleWindowMaximize:  function(){
						
						if(this.maximized){
							// we are currently maximized, so minimize it
							this.maximized = false;
							this.onResize();
							
						}else{
							// we are normal, maximize it
							this.maximized = true;
							this.onResize();	
							this.setDetailMode(2);						
						}
					 },					 

handleDecoratorsForZoom: function(){
						if(this.zoomer.getZoomPercentage() != 1){
                        	for(i=0; i<this.hotSpots.length; i++){
	                           this.hotSpots[i].toggleDecorators(false);                           
	                        }
                        }else{
                        	for(i=0; i<this.hotSpots.length; i++){
	                           this.hotSpots[i].toggleDecorators(this.getCookie().decoratorsOn);                           
	                        }
                        }  
					 },

zoomOut: 		     function(){
						this.zoomer.zoomOut();
						
						// figure out how much we should shift the
						// img to the left or right
						posInfo = this.getPositionInfo();
						zoomDelta = this.zoomer.getDelta();
						
						if(posInfo.l < 0){
							shiftPer = posInfo.l / posInfo.minLeft;
							newLeft = posInfo.l - (zoomDelta.w * shiftPer);
						}else{
							shiftPer = posInfo.l / posInfo.maxLeft;
							newLeft = posInfo.l + (zoomDelta.w * shiftPer);
						}
						
						this.dragable.element.setStyle({left: newLeft + 'px'});	
						
						// do this to keep the img in the visible area do matter what
						this.constrainDraggable(this.dragable);
						 
						for(i=0; i<this.hotSpots.length; i++){
                           this.hotSpots[i].zoomOut();                           
                        }
                        
                        this.handleDecoratorsForZoom();
                        this.handleLocationHashForZoom();                                                                      
					 },
					 
zoomIn: 		     function(){
						this.zoomer.zoomIn();
						
						// figure out how much we should shift the
						// img to the left or right
						posInfo = this.getPositionInfo();
						zoomDelta = this.zoomer.getDelta();
						
						if(posInfo.l < 0){
							shiftPer = posInfo.l / posInfo.minLeft;
							newLeft = posInfo.l + (zoomDelta.w * shiftPer);
						}else{
							shiftPer = posInfo.l / posInfo.maxLeft;
							newLeft = posInfo.l - (zoomDelta.w * shiftPer);
						}
						
						this.dragable.element.setStyle({left: newLeft + 'px'});
						
						// do this to keep the img in the visible area do matter what
						this.constrainDraggable(this.dragable);
						
						for(i=0; i<this.hotSpots.length; i++){
                           this.hotSpots[i].zoomIn();                           
                        }
                        
                        this.handleDecoratorsForZoom();
                        this.handleLocationHashForZoom();
					 },	
					 
zoomRestore: 		 function(){
						this.zoomer.restore();
						
						// do this to keep the img in the visible area do matter what
						this.constrainDraggable(this.dragable);
						
						for(i=0; i<this.hotSpots.length; i++){
                           this.hotSpots[i].zoomRestore();                           
                        }
                        
                        this.handleDecoratorsForZoom();
                        this.handleLocationHashForZoom();
					 },

handleLocationHashForZoom:  function(){
						this.addToLocationHash({zoom:this.zoomer.level});
					 },
					 
print: 		 		 function(){
                          printURL(this.printUrl);						
					 },					 					 				 
                     
setPwOnClass: 		function(className){
						els = document.getElementsByClassName(className);
						for(var i=0; i<els.length; i++) {
							els[i].pw = this;
						}											
					},                     
                     
getCookie:		     function()
                     {           
                     	if(this.cookie == null){
                        	this.cookie = new Object();							
                        }             
                        return this.cookie;
                     }, 
saveCookie:		     function()
                     {           
                     	this.cookieUtil.setObj(this.getCookie());
                     },

addToLocationHash:   function(obj)
                     {           
                     	if(obj){
                     		curHash = this.getLocationHash();
                     		
                     		for (var i in obj){
                     			if(typeof obj[i] == 'string' || typeof obj[i] == 'number') {
	                     			curHash[i] = obj[i];
                     			}
                     		}
                     		
                     		this.setLocationHash(curHash);                     		
                     	}
                     },

setLocationHash:     function(obj)
                     {           
                     	if(obj){
                     		location.hash = obj.toJSONString();
                     	}
                     }, 
                     
getLocationHash:     function()
                     {           
   						try {
      						var h = location.hash.substring(1,location.hash.length);
      						if(h){
      							// do a replace of %22 for double quote (fixes ie/ff difference)
      							h = h.replace(/%22/g,'"');
      							return eval('(' + h + ')');
      						}
      						
      						return {};
      						
    					} catch (e) {
    						 return {};
    					}   						                	
                     }                                         
};


/*--------------------------------------------------------------------------*/
/*  CLASS HotSpot  */
/*--------------------------------------------------------------------------*/
var HotSpot = Class.create();
HotSpot.prototype = {
initialize:          function(pw, id, left, top, data)
                     {
                        this.pw = pw;
                        this.id = id;
                        this.left = left; // - 7;
                        this.top = top - 1; // - 9;
                        this.width = 80;
                        this.height = 80;
                        this.zIndex = 200;
                        this.data = data;
                        this.data.id = id;
                        this.selected = false;
                     },
 
load:                function()
                     {    
                        this.insertHtml();
                        this.zoomer = new ImageZoomer(this.id, this.width, this.height, {minWidth: 0});
                        this.registerEvents();
                     },

                     
zoomOut:             function(){
						this.zoomer.zoomOut();
						
						zoomPer = this.zoomer.getZoomPercentage();						
						var newT = this.top * zoomPer;
						var newL = this.left * zoomPer;						
						this.position(newT, newL);						
					 },  
					 
zoomIn: 		     function(){
						this.zoomer.zoomIn();
						
						zoomPer = this.zoomer.getZoomPercentage();						
						var newT = this.top * zoomPer;
						var newL = this.left * zoomPer;						
						this.position(newT, newL);						
					 },	
					 
zoomRestore: 		 function(){
						this.zoomer.restore();
						this.position(this.top, this.left);						
					 },					                    

position: 		     function(top, left){						
						this.element.setStyle({                        					
                        					left:		left + 'px',
                        					top:		top + 'px'                        					                        					
                        					});						
					 },	

toggleDecorators:   function(turnOn, toggleClassSuffix){
						
						linkClass = this.pw.a2Id('hs_link');
						ownerClass = this.pw.a2Id('hs_owner');
						requireClass = this.pw.a2Id('hs_require');

						// remove all
						Element.removeClassName(this.element, linkClass);
						Element.removeClassName(this.element, ownerClass);
						Element.removeClassName(this.element, requireClass);
						
						// if we are turning the decorators on
						if(turnOn){						
							if(toggleClassSuffix == 'link'){
								toggleClass = linkClass;
								toggleList = this.data.links;
							}
							else if(toggleClassSuffix == 'owner'){
								toggleClass = ownerClass;
								toggleList = this.data.ownerList;
							}
							else if(toggleClassSuffix == 'require'){
								toggleClass = requireClass;
								toggleList = this.data.requirementsList;
							}
							
							// check that the list is not empty
							if(toggleList != undefined && toggleList.length > 0){
                        		Element.addClassName(this.element, toggleClass);
                        	}							
						}

					},
                
insertHtml:          function()
                     {
                        this.dragBox = this.pw.dragable.element;                        
                        imgSrc = this.pw.pixelImgSrc;
                                                
                        new Insertion.Bottom(this.dragBox, '<img id="'+this.id+'" src="'+imgSrc+'">');
                        Element.addClassName(this.id, this.pw.a2Id('hs_unselected'));
                        
                        // The Div 
                        this.element = $(this.id);
                        this.element.hotspot = this;
                        
                        this.element.setStyle({
                        					zIndex: 	this.zIndex,
                        					position:	'absolute',
                        					left:		this.left + 'px',
                        					top:		this.top + 'px',
                        					width:		this.width + 'px',
                       						height:		this.height + 'px',
                        					cursor:		'pointer',
                        					margin:		'0px',
                        					padding:	'0px'                        					
                        					});
                        
                        //this.element.setStyle({border: '2px dotted gray'});
                     },

registerEvents:      function()
                     {        
                     	Event.observe(this.id, 'click', this.onClick.bindAsEventListener(this));
                     	Event.observe(this.id, 'dblclick', this.onDoubleClick.bindAsEventListener(this));
                     	Event.observe(this.id, 'mouseover', this.onMouseOver.bindAsEventListener(this));
                     	Event.observe(this.id, 'mouseout', this.onMouseOut.bindAsEventListener(this));
                     },
                     
onClick:             function(e)
                     {                        
                        this.select(e);                                             
                     },
                     
onDoubleClick:       function(e)
                     {
                       this.log("double clicked: " + this.data.dblclick +", "+ this.data.name + ", " + this.data.desc + ", " + this.data.links + ", " + this.data.testPlan + ", " + this.data.ownerList + ", " + this.data.risksList + ", " + this.data.requirementsList + ", " + this.data.standardsList + ", " + this.data.suppliersList + ", " + this.data.inputsList + ", " + this.data.outputsList + ", " + this.data.customersList + ", " + this.data.assignedPersonnelList + ", " + this.data.performedByList + ", " + this.data.financialStatement + ", " + this.data.testingOwner + ", " + this.data.testingContacts + ", " + this.data.testResults + ", " + this.data.supportingDocumentation + ", " + this.data.approvalList + ", " + this.data.distributionList + ", " + this.data.documentId + ", " + this.data.recordId + ", " + this.data.purpose + ", " + this.data.scope + ", " + this.data.definitions + ", " + this.data.responsibilities + ", " + this.data.procedures + ", " + this.data.location + ", " + this.data.disposal);
                       
                       if(this.data.dblclick){
                       		if(this.data.dblclickNewWindow && this.data.dblclickNewWindow == 'true'){
                       			window.open(this.data.dblclick);
                       		}else{
                       			location.href=this.data.dblclick;
                       		}			
                       }
                     },
                     
onMouseOver:         function(e)
                     {
                       //this.log('mouse over: ' + e.clientX + ", " + e.clientY);  
                       //this.showPopUp();
                     },
                     
onMouseOut:          function(e)
                     {
                       this.hidePopUp();
                     },
                     
select:              function(e)
                     {       
                        this.log("selected: " + this.data.name + ", " + this.data.desc + ", " + this.data.personTitle + ", " + this.data.department + ", " + this.data.phone + ", " + this.data.email + ", " + this.data.links + ", " + this.data.testPlan + ", " + this.data.ownerList + ", " + this.data.risksList + ", " + this.data.requirementsList + ", " + this.data.standardsList + ", " + this.data.suppliersList + ", " + this.data.inputsList + ", " + this.data.outputsList + ", " + this.data.customersList + ", " + this.data.assignedPersonnelList + ", " + this.data.performedByList + ", " + this.data.relatedProcessMaps + ", " + this.data.financialStatement + ", " + this.data.testingOwner + ", " + this.data.testingContacts + ", " + this.data.testResults + ", " + this.data.supportingDocumentation + ", " + this.data.approvalList + ", " + this.data.distributionList + ", " + this.data.supervisorList + ", " + this.data.assignedTo + ", " + this.data.directReports + ", " + this.data.diectResponsibilities + ", " + this.data.documentId + ", " + this.data.recordId + ", " + this.data.purpose + ", " + this.data.scope + ", " + this.data.definitions + ", " + this.data.responsibilities + ", " + this.data.procedures + ", " + this.data.location + ", " + this.data.disposal);
                        
                        if(this.pw.selectedHotSpot != null && this.pw.selectedHotSpot.id != this.id ){
                           this.pw.selectedHotSpot.unselect();
                        }
                        this.pw.selectedHotSpot = this;
                        this.selected = true;
                        //this.element.setStyle({border: 	'2px solid #BFA7A8'});
                        
                        Element.addClassName(this.element, this.pw.a2Id('hs_selected'));
                        Element.removeClassName(this.element, this.pw.a2Id('hs_unselected'));
                        
                        //this.log('selected: ' +  Element.classNames(this.element).toString());
                        
                        this.element.src = this.pw.diagramIndicator; 
                                
                        if(Element.hasClassName(this.element, this.pw.a2Id('hasDecorator'))){
                        	this.element.src = this.pw.diagramIndicatorHasDec;
                        }
                                     
                        if(this.pw.getDetailMode() == 1){
                        	this.showWindow();
                        }else if(this.pw.getDetailMode() == 2){
                        	this.showPopUp(e);
                        }else{
                        	this.showWindow();
                        }             
					   
					   this.pw.addToLocationHash({sel:this.id});
                                                                        
                        //this.showWindow();   
                        //this.showPopUp();                     
                     },
                     
unselect:            function()
                     {                        
                        this.log('unselected:');
                        //this.element.setStyle({border: 	'0px none white'});
                        Element.addClassName(this.element, this.pw.a2Id('hs_unselected'));
                        Element.removeClassName(this.element, this.pw.a2Id('hs_selected'));
                        this.element.src = this.pw.pixelImgSrc;
                        this.selected = false;
                        this.hideWindow();  
                        //this.log('unselected: ' +  Element.classNames(this.element).toString());                      
                     },                     

showPopUp:           function(e)
                     {
                     	this.log('showPopUp');
                        if(this.popUp == null){
                           
                           options =   {
                                          offsetTop: -55,
                                          offsetLeft: 28,
                                          positionParent: this.element
                                       };
                           
                           this.popUp = new PopUpWindow(this.id+'popUp',options);
                           this.popUp.hs = this; 
                           
                           html = this.pw.buildPopUpDetailsHTML(this.data);
                           
                           this.popUp.setContent(html);
                        }   
                                                 
                        this.popUp.show(e);       
                        
                        this.pw.setPwOnClass(this.pw.a2Id('MoreDetailsLink'));                                        
                     },
                     
hidePopUp:           function()
                     {
                        if(this.popUp != null){
                           
                           this.popUp.hideSoon();
                        }
                     },
                     
showWindow:          function()
                     {
                     	this.pw.updateDetailsWindow(this.data); 
                     },
                     
hideWindow:          function()
                     {
                        if(this.win != null){
                           
                           //this.win.element.style.border = '';
                           this.win.getContent().style.background = '#FDFDFD';
                           
                           /* If the window has NOT been moved, hide it*/
                           if(this.win.hasBeenMoved == null || !this.win.hasBeenMoved){
                              this.win.hide();
                           }                                                
                        }
                     },
                     
log:                 function(str)
                     {
                        //this.pw.debug.log('HotSpot('+this.id+') : '+ str);
                        this.pw.debug.log('HS: '+ str);
                     }
};


/*--------------------------------------------------------------------------*/
/*  CLASS PopUpWindow  */
/*--------------------------------------------------------------------------*/
var PopUpWindow = Class.create();
PopUpWindow.prototype = {
initialize:          function(elementId)
                     {
                     	this.popUpWidth = 240;
                     	this.popUpHeight = 150;
                     	
                        this.options = Object.extend(new DefaultWinOptions(),
                              {
                                 width: this.popUpWidth,
                                 height: this.popUpHeight, 
                                 minWidth: 60,
                                 minHeight: 20,
                                 closable: true,
                                 minimizable: false,
                                 maximizable: false,
                                 hideTimeout: 1000,
                                 offsetTop: -15,
                                 offsetLeft: 30,
                                 positionParent: null
                              });  
                          
                       this.options = Object.extend(this.options, arguments[1] || {});
                        
                       this.id = elementId;
                       this.log('PopUpWindow.initialize('+this.id+')');
                       
                       this.win = new Window(this.id, this.options);                        
                       this.element = this.win.element;
                       
                       this.win.element.popUp = this;
                       
                       this.moving = false;
                       this.resizing = false;
                       
                       this.initPinButton();
                       this.registerEvents();
                       
                       if(!GLOBAL.visiblePopups){
                          GLOBAL.visiblePopups = new Array();
                       }
                       
                     },
                     
inspect:             function(){
                        return 'PopUp('+this.id+')';
                     },                        
                     
initPinButton:       function()
                     {
                        pinClassName = this.options.className + '_pin';
                        
                        pinId = this.id + '_pin';                        
                        html = '<div class="'+pinClassName+'" id="'+pinId+'" onmouseup="this.popUp.pin()"> </div>';
                                                
                        new Insertion.Top(this.element, html);
                        
                        this.pinElement = $(pinId);                        
                        this.pinElement.popUp = this;
                        
                        pinOffClassName = this.options.className + '_pin_off';
                        Element.addClassName(this.pinElement, pinOffClassName);
                     },

registerEvents:      function()
                     {                          
                        Event.observe(this.id, 'mouseover', this.onMouseOver.bindAsEventListener(this));
                        Event.observe(this.id, 'mouseout' , this.onMouseOut.bindAsEventListener(this));                        
                     },
                     
onMouseOver:         function(e)
                     {        
                        //this.log('onMouseOver');                        
                        this.cancelHide();
                     },
                     
onMouseOut:          function(e)
                     {         
                        //this.log('onMouseOut'); 
                        this.win.getContent().style.background = '#FFFFFF';
                        this.hideSoon();
                     },
                     
onStartMove:         function()
                     {
                        //this.log('onStartMove');
                        this.moving = true;
                     },
                     
onEndMove:           function(eventName,win)
                     {    
                        //this.log('onEndMove');
                        this.moving = false;
                     },  
                     
                     
onStartResize:       function()
                     {
                        //this.log('onStartResize');
                        this.resizing = true;
                     },
                     
onEndResize:         function()
                     {
                        //this.log('onEndResize');
                        this.resizing = false;
                     },
                     
                     
setContent:          function(content)
                     {
                        html = '<div><div style ="width: 100%;">'+content+'</div></div>';
                        this.win.getContent().innerHTML= html;
                     },
                     
show:                function(e)
                     {         
                     	this.log('show()');
                      
                        this.hidePopUpsInVisArr();
                        
                        this.cancelHide();
                                                
                        if(!this.win.isVisible()){
                           this.positionOffParent(e);
                        }
                        
                        if(this.pinned){
                           this.win.getContent().style.background = '#FFFFDF';
                        }
                        
                        Windows.focusedWindow = null;
                        this.win.toFront();
                        this.win.show();  
                        this.win.getContent().setStyle({overflow: 'auto'});                     
                                              
                        this.addToVisArr();
                        
                     },
                     
cancelHide:          function()
                     {                        
                        if(this.hideSoonId != null){
                           clearTimeout(this.hideSoonId);                           
                        }
                     },                     

hideSoon:            function()
                     {        
                        this.win.getContent().style.background = '#FFFFFF';
                        
                        thisPopUp = this;
                        this.cancelHide();                       
                        this.hideSoonId = setTimeout(thisPopUp.hide.bind(this), this.options.hideTimeout);
                     },
                     
hide:                function()
                     {       
                        if(!this.pinned && !this.moving && !this.resizing){
                           
                           // Remove this popup from the GLOBAL.visiblePopups array
                           this.removeFromVisArr();
                           
                           this.win.hide(); 
                        }
                     },

hidePopUpsInVisArr:  function()
                     {
                        thisPopUp = this;
                        if(GLOBAL.visiblePopups && GLOBAL.visiblePopups.length > 0){
                           GLOBAL.visiblePopups.each(
                                 function(popUp){
                                    if(popUp.id != thisPopUp.id){
                                       popUp.hide();
                                    }
                                 });
                        }
                     },
                     
addToVisArr:         function()
                     {
                        containsPopup = GLOBAL.visiblePopups.include(this);
                        
                        if(!containsPopup){                           
                           GLOBAL.visiblePopups.push(this);
                        }  
                     },
                     
removeFromVisArr:    function()
                     {
                        thisPopUp = this;                           
                        GLOBAL.visiblePopups = GLOBAL.visiblePopups.findAll(                                 
                              function(popUp){
                                 return (popUp.id != thisPopUp.id);
                              }
                        );                        
                     },
                     
pin:                 function()
                     {
                        pinOffClassName = this.options.className + '_pin_off';
                        pinOnClassName = this.options.className + '_pin_on';
                        
                        if(this.pinned){
                           this.pinned = false;
                           
                           Element.addClassName(this.pinElement, pinOffClassName);
                           Element.removeClassName(this.pinElement, pinOnClassName);
                           
                           this.hide();
                        }else{
                           this.pinned = true;
                           
                           Element.addClassName(this.pinElement, pinOnClassName);
                           Element.removeClassName(this.pinElement, pinOffClassName);
                        }
                        
                        this.log('Pinned!!! ' + this.id + ', ' + this.pinned);
                     },
                     
positionOffParent:   function(e)
                     {
                     	this.log('positionOffParent()');
                     	
                     	page = WindowUtilities.getPageSize();
                     	if(false){
	                     	this.log('winW, winH       '+page.windowWidth + ',' +page.windowHeight);
	                     	this.log('pageW, pageH     '+page.pageWidth + ',' +page.pageHeight);
	                     	// not in IE - this.log('pageX, pageY     '+ e.pageX + ', ' + e.pageY);                     	
	                     	this.log('clientX, clientY '+ e.clientX + ', ' + e.clientY);
	                     	this.log('screenX, screenY '+ e.screenX + ', ' + e.screenY);
                     	}
                     	
                     	if(options.positionParent){ 
                     	
                     		var pos = Position.page(this.options.positionParent);
                           	//this.log('parent pos    -> top:' + pos[1]+ ' left:' + pos[0]);
                     		var t = pos[1] + this.options.offsetTop - this.options.height;
                           	var l = pos[0] + this.options.offsetLeft;
                     	
	                     	if(this.hs.pw.maximized){
	                     		var posOff = Position.realOffset(this.options.positionParent);
                           		//this.log('parent posOff -> top:' + posOff[1]+ ' left:' + posOff[0]);
	                     		var t = t + posOff[1];
	                     	}
	                     	
	                     	// handle popups going off the right of the screen
	                     	popLocationFactor = e.clientX + this.popUpWidth + 50;
	                     	//this.log('popLocationFactor:' + popLocationFactor);
	                     	
	                     	zp = this.hs.pw.zoomer.zPercentage;
	                     	
	                        if(popLocationFactor > page.pageWidth && t < 0){
	                        	//this.log('adjusting left -> old l' + l);
	                     		t = t + this.options.height + (zp*138);
	                        	l = l - this.popUpWidth - zp*(58); 
	                     	}
	                        else if(popLocationFactor > page.pageWidth){
	                        	//this.log('adjusting left -> old l' + l);
	                        	l = l - this.popUpWidth - zp*(28); 
	                        }
	                     	else if(t < 0){
	                     		// handle popups going off top of screen
	                     		t = t + this.options.height + (zp*138);
	                     		l = l + (zp*33);
	                     	}
	                     	
	                     	this.log('new pos -> top:' + t + ' left:' + l);
	                     	this.win.setLocation(t,l);
                     	}
                        
                     },
                     
log:                 function(str)
                     {
                     	Try.these	(                     			
					      		 	function() {pw.debug.log('PopUpWindow - ' + str);},
					      		 	function() {pW.debug.log('PopUpWindow - ' + str);},
					      		 	function() {processWebsite.debug.log('PopUpWindow - ' + str);}					      								      
					    		  	);
                     }
                     
};



/*--------------------------------------------------------------------------*/
/*  CLASS WindowObserver  */
/*--------------------------------------------------------------------------*/
var WindowObserver = Class.create();
WindowObserver.prototype = {
initialize:          function() {},
onStartResize:       function(eventName,win)
                     {
                        if(win.element.popUp){
                           win.element.popUp.onStartResize();
                        }
                     },
                     
onEndResize:         function(eventName,win)
                     {
                        if(win.element.popUp){
                           win.element.popUp.onEndResize();
                        }
                     },

onStartMove:         function(eventName,win)
                     {
                        win.hasBeenMoved = true;
                        if(win.element.popUp){
                           win.element.popUp.onStartMove();
                        }
                     },
                     
onEndMove:           function(eventName,win)
                     {    
                        if(win.element.popUp){
                           win.element.popUp.onEndMove();
                        }
                     },
                     
onClose:             function(eventName,win)
                     {
                        win.hasBeenMoved = false; 
                     },
onDestroy:           function(eventName,win) {},
onMaximize:          function(eventName,win) {},
onMinimize:          function(eventName,win) {},
onFocus:             function(eventName,win) {},
onHide:              function(eventName,win)
                     {
                        win.hasBeenMoved = false;
                     },
onShow:              function(eventName,win) {}                     
};



/*--------------------------------------------------------------------------*/
/*  CLASS DefaultWinOptions  */
/*--------------------------------------------------------------------------*/
var DefaultWinOptions = Class.create();
DefaultWinOptions.prototype = {
initialize:          function()
                     {
                        this.className    =    "mac_os_x";                           
                        this.resizable    =    true;
                        this.closable     =    true;
                        this.minimizable  =    true;
                        this.maximizable  =    true;
                        this.draggable    =    true;                           
                        this.showEffect   =    Element.show;
                        this.hideEffect   =    Element.hide;                           
                        this.title        =    "&nbsp;";                           
                        this.opacity      =    1;
                        this.zIndex       =    100;
                     }
};


/*--------------------------------------------------------------------------*/
/*  CLASS ImageZoomer  */
/*--------------------------------------------------------------------------*/
var ImageZoomer = Class.create();
ImageZoomer.prototype = {
initialize:          function(imgElement, imgWidth, imgHeight) {

						this.imgElement = $(imgElement);
						//$(imgElement).setStyle({border: '2px solid #669933'});
						this.originalWidth = imgWidth;
						this.originalHeight = imgHeight;
						
						this.level = 0;
						this.zPercentage = 1;

						this.options = Object.extend({						      							
						      							zoomFactor:  .1,
						      							minZoomPercent: .299,
						      							maxZoomPercent: 2.0,
						      							useDynamicImage: false,
						      							dynamicImageUrlFunction: Prototype.emptyFunction						      							
													 }
													 , arguments[3] || {});

					 },

zoomIn:		         function()
					 {
						this.doZoom(true);
					 },

zoomOut:             function()
					 {
						this.doZoom(false);
					 },

restore:             function()
					 {						
						this.level = 0;
						this.zPercentage = 1;
												
						if(this.options.useDynamicImage){						
							Element.setStyle(this.imgElement, {width:this.originalWidth, height:this.originalHeight});
							this.switchDynamicImage();						
						}else{						
							Element.setStyle(this.imgElement, {width:this.originalWidth, height:this.originalHeight});
						}						
					 },

getZoomPercentage:   function()
					 {
						return this.zPercentage;
					 },
					 
getDelta:   		 function()
					 {
						return {w: (this.newWidth - this.previousDims.width),
								h: (this.newHeight - this.previousDims.height)}; 
					 },

computeZoomPer:      function(zFac, level)
					 {
						var zPer = (zFac * level) + 1;
						
						if(level > 0){
							zPer = (zFac * level * 2.5) + 1;
						}						
						
						//this.log(level + ' | ' + zPer + ' | ' + zFac);
						return zPer;
					 },

doZoom:		         function(zoomIn){
						zFac = this.options.zoomFactor;
						if(!zoomIn){							
							this.level = this.level - 1;
						}else{
							this.level = this.level + 1;
						}
						
						this.zPercentage = this.computeZoomPer(zFac, this.level);
						
						if(this.zPercentage < 0){
							this.zPercentage = -1 * this.zPercentage;
							this.zPercentage = 1/this.zPercentage;
						}
						
						if(this.zPercentage < this.options.minZoomPercent){
							this.zPercentage = this.options.minZoomPercent;
							this.level = this.level + 1;
						}
						
						if(this.zPercentage > this.options.maxZoomPercent){
							this.zPercentage = this.options.maxZoomPercent;
							this.level = this.level - 1;
						}
						
						this.previousDims = Element.getDimensions(this.imgElement);
						
						this.newWidth = this.originalWidth * this.zPercentage;
						this.newHeight = (this.newWidth/this.originalWidth) * this.originalHeight;

						if(this.options.useDynamicImage){
						   Element.setStyle(this.imgElement, {width:this.newWidth, height:this.newHeight});
						   this.switchDynamicImage();			
						}else{
							Element.setStyle(this.imgElement, {width:this.newWidth, height:this.newHeight});
						}
												
					 },

switchDynamicImage: function(){
	
						var newSrc = this.options.dynamicImageUrlFunction(this.zPercentage);
							
						newImg = new Image();
						
						newImg.onload = function(){
						       this.imgElement.src = newImg.src;
						       this.imgElement.width = newImg.width;
						       this.imgElement.height = newImg.height;
						       this.newWidth = newImg.width;
							   this.newHeight = newImg.height;						       
						}.bind(this);
						
						newImg.src = newSrc;							
						
						//this.log(this.zPercentage + ' - ' + this.newWidth + ' x ' + this.newHeight);						   
					 },

log:             	 function(str)
					 {
						if(this.debug != undefined && this.debug != null){
							this.debug.log('ImageZoomer: '+str);
						}
					 }							 
};


/*--------------------------------------------------------------------------*/
/*  CLASS DebugLogger  */
/*--------------------------------------------------------------------------*/
var DebugLogger = Class.create();
DebugLogger.prototype = {
initialize:          function(id)
                     {       
                     	if(SYNTHIS_DEBUG != null){
                           this.DEBUG = SYNTHIS_DEBUG;
                        }else{
                           this.DEBUG = false;
                        }
                     	  
                     	if(this.DEBUG){      
                     	      
                     	    if(!SYNTHIS_DEBUG_LEFT){
                     	    	SYNTHIS_DEBUG_LEFT = 10;
                     	    }  
                     	      
	                     	this.id = id;
	                     	
	                     	options = Object.extend(new DefaultWinOptions(),
	                              {
	                              width:300,
	                              height:350,
	                              closable: true,
	                              minimizable: true,
	                              maximizable: true,
	                              title: "Debug Log"
	                              });
	                     	
	                     	html = '';
	                        html = html + '<p><b>DEBUG LOG</b></p>';                        
	                        html = html + '<div id="debugReplace'+id+'">';                        
	                        html = html + '</div>';
	                        html = html + '<br><textarea rows="19" cols="60" id="debug'+id+'"></textarea>';
	                        
	                        this.win = new Window('debugWindow', options);
	                        this.win.setZIndex(1);
	                        this.win.setLocation(3,SYNTHIS_DEBUG_LEFT);
	                        new Insertion.Bottom(this.win.getContent(), html);                     	
	                     	this.win.minimize();
	                     	this.win.show();
	                     	
	                        this.element = $('debug'+id); 
	                        this.replaceEl = $('debugReplace'+id);
	                        
	                        Element.setStyle(this.element,{fontSize:'10px', fontFamily:'arial'});
	                        
	                        this.clear();
	                        this.replace('Debug Replacement Area');
                     	}
                     },
                     
log:                 function(str)
                     {
                        if(this.DEBUG && this.element != null){
                           val = this.element.value;
                           
                           if(val.length > 3000){
                              val = '';
                           }
                           
                           this.element.value = str + '\n' + val;
                        }
                     },
                     
replace:             function(str)
                     {
                        if(this.DEBUG && this.replaceEl != null){
                           this.replaceEl.innerHTML = str;                           
                        }
                     },
                     
clear:               function()
                     {
                        if(this.DEBUG){
                           if(this.element != null){
                              this.element.value = '';
                           }  
                           this.replace('cleared!');
                        }
                     }
};

/*--------------------------------------------------------------------------*/
/*  CLASS CookieUtil  */
/*--------------------------------------------------------------------------*/
var CookieUtil = Class.create();
CookieUtil.prototype = {
initialize:          function(name, val, debug)
                     {
                        this.name     =  name;
                        this.debug    =  debug;
                        this.DEBUG_ON =  false;                        
                        if(val != null){
                        	this.set(val);
                        } 
                     },
                     
get: 		         function()
                     {
                        this.log("get(" + this.name +")");   
      
					    var start = document.cookie.indexOf(this.name+"=");
					    var len = start+this.name.length+1;
					    
					    if ((!start) && (this.name != document.cookie.substring(0,this.name.length)))
					        return null;
					
					    if (start == -1)
					        return null;
					    
					    var end = document.cookie.indexOf(";",len);
					    
					    if (end == -1)
					        end = document.cookie.length;
					
					    var cookieText = unescape(document.cookie.substring(len,end));
					       
					    this.log(" get() returns: " + cookieText);
					    
					    return cookieText;                          
                        
                     },
set: 		         function(value,expires,path,domain,secure)
                     {
                        this.log("set(" + value +")");
                        
						if(path == null){
							path = '/';
						}	
						
					   var cookieText = this.name + "=" +escape(value) +
					                      ( (expires) ? ";expires=" + expires.toGMTString() : "") +
					                      ( (path) ? ";path=" + path : "") + 
					                      ( (domain) ? ";domain=" + domain : "") +
					                      ( (secure) ? ";secure" : "");   
					         
					   this.log(" set() setting: " + cookieText);      
					         
					   document.cookie = cookieText;                          
                        
                     },
getObj:	         	function()
                     {                          
                        var json = this.get();
                        this.log("getObj(" + json +")");   
                      
                      	if(json != null){
                      		return eval('(' + json + ')');
                      	}
                     },
setObj:	         	function(obj)
                     {                          
                     	var json = obj.toJSONString();
                      	this.log("setObj(" + json +")");   
                      	
                      	if(json != null){
                      		this.set(json);
                      	}                      	
                     },                                          
log: 		         function(str)
                     {
                     	if(this.DEBUG_ON){
                        	if(this.debug != null){                        	
                        		this.debug.log('CookieUtil: ' + str);
                        	}
                        }                        
                     }                                                                 
};


/*--------------------------------------------------------------------------*/
/*  CLASS StringBuffer  */
/*--------------------------------------------------------------------------*/
var StringBuffer = Class.create();
StringBuffer.prototype = {
initialize:          function()
                     {
                       this.buffer = [];
                     },
append: 		     function(str)
                     {
                         this.buffer.push(str);
                         return this;                   
                     },
toString: 		     function()
                     {
                     	return this.buffer.join("");                        
                     }                                            
};



/*--------------------------------------------------------------------------*/
/* HELPER FUNCTIONS */
/*--------------------------------------------------------------------------*/

function exists(obj){	
	if (obj == undefined){
		 return false;
	}
	if (object == null){
		 return false;
	}	 
	return true;
}

function showObj(obj, fields){
	buf = new StringBuffer();
	for(i = 0; i < fields.length; i++){
		var value = obj[fields[i]];
		buf.append(fields[i]).append('=').append(value);
		if(i < fields.length-1){
			buf.append(',');
		}
	}
	return buf.toString();	
}

//Output list of properties for the object
function dumpProps(objName)
{
   var obj = eval(objName)
   var msg = ""
   var count = 0
   var maxProps = 20
   // Loop through properties of the object
   for (var i in obj) {
      if (i != "outerHTML" && i != "outerText" && i != "innerHTML" && i != "innerText" && i != "domain") {
         msg += objName + "." + i + "=" + obj[i] + "\n"
         if (count > maxProps) {
            // Output a batch           
            alert(msg);           
            msg = ""
            count = 0
            continue
         }
         count++
      }
   }
   // Output any leftovers
   alert(msg);
}

function dumpPropsToString(objName)
{
   var fullStr = "";
   var obj = eval(objName)
   var msg = ""
   var count = 0
   var maxProps = 20
   // Loop through properties of the object
   for (var i in obj) {
      if (i != "outerHTML" && i != "outerText" && i != "innerHTML" && i != "innerText" && i != "domain") {
         msg += objName + "." + i + "=" + obj[i] + "\n"
         if (count > maxProps) {
            // Output a batch           
            //alert(msg);
            fullStr = fullStr + msg;
            msg = ""
            count = 0
            continue
         }
         count++
      }
   }
   // Output any leftovers
   //alert(msg);
   fullStr = fullStr + msg;
   return fullStr;
}

/* This is used with Event.observe to find
 * the first non null prop off of the event element
 * searching up the tree  */
function findFirstNonNullProp(event, propName){
   evEl = Event.element(event);
   if(evEl){
      while (evEl.parentNode && !evEl[propName]){
         evEl = evEl.parentNode;                                           
      }
      return evEl[propName];
   }
   
   return null;
   
}

   