var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;

var WidgetParent = Class.create({
								   
	/*
	##################################################################
	initialize: this function is called when instantiating this class
	##################################################################
	*/
	initialize: function(obj) {
		for (property in obj){
			this[property] = obj[property];
		}
		
		this.draw();
	},
		
	id: '',
	
	style: '',
	
	width:'100%',
	
	height:'500px',
	
	arrayWidgets: new Array(),
	
	arrayDropTargets:new Array(),
	
	arrayContainers: new Array(),
	
	draggingWidget: -1,

	dragging:false,
	
	parentPosition:'', //the top and left to calculate dragging bounds [Number, Number] also accessible as { left: Number, top: Number }
	
	parentScrollOffset:'', // the scroll offsets from within a div.. we need this for ie since it is a horrible browser. { left: Number, top: Number }
	
	parentDimensions:'', //the height and width of parent when drag starts. {height: Number, width: Number}
	
	scrollHeight:'',
	
	tabset:'', //the tab object we are in so we can pop to a new tab.
	
	draw: function(){
		document.getElementById(this.id).style.className = this.style;
					
	},
	
	getEl:function(){
		return document.getElementById(this.id);	
	},
		
		
	setDropRange:function(dropIndex){
		
		dropDiv = this.arrayDropTargets[dropIndex];
		//dropDiv.style.display = '';
		$(dropDiv.id).show();
		
		
		/*
		this.arrayDropTargets[dropIndex].left = $(dropDiv.id).viewportOffset().left;
		var topcalc = 0 
		if(isIE){topcalc = $(this.id).scrollTop;} 
		this.arrayDropTargets[dropIndex].top = $(dropDiv.id).viewportOffset().top + topcalc;
		this.arrayDropTargets[dropIndex].right = (this.arrayDropTargets[dropIndex].left + $(dropDiv.id).getDimensions().width);
		this.arrayDropTargets[dropIndex].bottom = (this.arrayDropTargets[dropIndex].top + $(dropDiv.id).getDimensions().height);
		*/
		
		var dropOffset = $(dropDiv.id).cumulativeOffset();
		this.arrayDropTargets[dropIndex].left = dropOffset.left;
		this.arrayDropTargets[dropIndex].top =  dropOffset.top;
		
		var dropDimensions = $(dropDiv.id).getDimensions();
		this.arrayDropTargets[dropIndex].right = (this.arrayDropTargets[dropIndex].left + dropDimensions.width);
		this.arrayDropTargets[dropIndex].bottom = (this.arrayDropTargets[dropIndex].top + dropDimensions.height);
		
		
		
		
		
		$(dropDiv.id).hide();
		//this.arrayDropTargets[dropIndex].innerHTML = ' top: ' + this.arrayDropTargets[dropIndex].top + ' left: ' + this.arrayDropTargets[dropIndex].left;
		
	},
	
	getDropIndexByName:function(id){
		
		for(var i=0;i<this.arrayDropTargets.length;i++){
			if(this.arrayDropTargets[i].id == id){
				return i;
				break;
			}//end if
			
		}//end for
		
	},
	
	
	removeDropObject: function(dropObjectId){
		//remove the drop object from the array
		this.arrayDropTargets.splice(this.getDropIndexByName(dropObjectId),1);
		//$(dropObjectId).parentNode.removeChild(dropObjectId);
		$(dropObjectId).remove();
		//alert('removed');
		
	},
	
	
	resizeDropObject: function(i){
			
		$(this.arrayDropTargets[i].id).setStyle({height:this.arrayDropTargets[i].classHeight + 'px'});	
		
		//this.arrayDropTargets[i].style.height = this.arrayDropTargets[dropIndex].classHeight + 'px';
	},
	
	
	resetDropObjects: function(){
			
			for(var i=0;i<this.arrayDropTargets.length;i++){
				this.resizeDropObject(i);
			}//end for

			for(var i=0;i<this.arrayDropTargets.length;i++){
				this.setDropRange(i);
			}//end for

	},
	
	getContainerById: function(id){
		
		for(var i=0;i< this.arrayContainers.length;i++){
			if(this.arrayContainers[i].id == id) { 
				return this.arrayContainers[i];
			}
		}// end for
	},
	
	getWidgetByMainId: function(id){
		
		for(var i=0;i< this.arrayWidgets.length;i++){
			if(this.arrayWidgets[i].maindivID == id) { 
				return this.arrayWidgets[i];
			}
		}// end for
	},
	
	updateSortOrder: function(){
	
		for(var i=0;i< this.arrayContainers.length;i++){
			// we also need to figure out the sort order
			var containerchildren = $(this.arrayContainers[i].id).childElements();
			var sortorder = 1
			for(var j=0;j<containerchildren.length;j++){
				
				// look for main div
				if(containerchildren[j].id.substring(0,7) == 'mainDiv'){
					var temp_widget = this.getWidgetByMainId(containerchildren[j].id);
					//alert('c: ' + this.arrayContainers[i].ac_id + ' w: ' + containerchildren[j].id + ' sort: ' + sortorder + ' cp_id: ' + temp_widget.cp_id);
					/*
					##########################################################################################
					UPDATE DATABASE 
					##########################################################################################
					*/	
					
					Ext.Ajax.request({
						url:'update_customer_layout.cfm'
						,params:{ac_id:this.arrayContainers[i].ac_id,cp_id:temp_widget.cp_id,sort:sortorder}
						,method:'GET'
						,success:function(responseObj,optionsObj){
						}
						,failure:function(responseObj,optionsObj){
						}
					});
					sortorder = sortorder + 1;
				}
				
				//alert(containerchildren[i].id);
			}// end for children
			
			
		}// end for containers
			
	}, // end updateSortOrder
	
	adjustHeight:function(){
		//alert(this.width);
		var newheight = $(this.id).getHeight();
		for(var i=0;i< this.arrayContainers.length;i++){
			var columnHeight = $(this.arrayContainers[i]).getChildHeight();
			if( columnHeight > newheight){
				newheight = columnHeight
			}//end if
			
		}// end for
		
		$(this.id).setStyle({height: newheight + 'px'});
		$(this.id).setStyle({width: this.width});
		if(this.tabset.height < newheight){
			this.tabset.setHeight(newheight);
		}

		
		return newheight;
		
	}// end function
});


/*
############################################################################################
function createContainer

Parameters:
parent - the parent div for the container.
id - the unique name if the container
width - width in pixels or %
height - height in pixels or %
x- not used yet
y - not used yet.

Description:
This function creates a container to hold plugins. Usually contaners are a column that will hold various plugins. 

############################################################################################

*/


var WidgetContainer = Class.create({
	/*
	##################################################################
	initialize: this function is called when instantiating this class
	##################################################################
	*/
	initialize: function(obj) {
		for (property in obj){
			this[property] = obj[property];
		}
		
		// append to parent array
		arrayIndex = this.parent.arrayContainers.push(this) - 1;
		this.draw();
	},
	
	ac_id: 0, //db id for this container
	
	arrayIndex: 0, //my array index
	
	parent: '', //the parent object
	
	id: '', // the container id
	
	style: '', //the style to use
	
	width:0,
	
	height:0,
	
	footerdivID:'',
	
	dropTargetStyle:'dragRectangleDiv',
	
	getEl:function(){
		return document.getElementById(this.id);	
	},
	
	

	
	draw: function(){
		

			
			
			var containerDiv = document.createElement('DIV');
			containerDiv.style.cssText = 'width:' + this.width + ';height:' + this.height + ';';
			containerDiv.style.height= this.height;
			containerDiv.style.width = this.width;
			containerDiv.className = this.style;
			containerDiv.id = this.id;
			
			this.parent.getEl().appendChild(containerDiv);
			
			
			//blank space at the bottom so we can scroll under the last widget
			var footerDiv = document.createElement('DIV');
			footerDiv.style.cssText = 'width:' + this.width + ';height:500px;';
			footerDiv.style.height= '100px';
			footerDiv.style.width = this.width;
			this.footerdivID = 'f_' + this.id;
			footerDiv.id = this.footerdivID;
			this.getEl().appendChild(footerDiv);			
			
			this.addDropTarget(this,null);
			
			
			
			
	},
		
	addDropTarget:function(parent,ap_id){
			
		var dropdiv  = document.createElement('DIV');
		dropdiv.className = this.dropTargetStyle;
		dropdivID = 'dropDiv_' + parent.id;
		dropdiv.id = dropdivID;
		dropdiv.ap_id = ap_id;
		dropdiv.parent = parent;
		
		//this.getEl().appendChild(dropdiv);
		this.getEl().insertBefore(dropdiv,document.getElementById(this.footerdivID));
		//$(this.footerdivID).insert(dropdiv,{position:'before'});
		
		dropIndex = this.parent.arrayDropTargets.push(dropdiv) - 1;
		
		this.parent.arrayDropTargets[dropIndex].classHeight = dropdiv.offsetHeight;
		this.parent.arrayDropTargets[dropIndex].ap_id = ap_id;
		
		dropdiv.style.height = dropdiv.offsetHeight + 'px';
		dropdiv.innerHTML = 'Release your mouse button to drop this widget here.';
		
		$(dropdiv.id).hide();
		
		//this.parent.setDropRange(dropIndex,ap_id);
		
		//dropdiv.style.display = 'none';
		
		return dropIndex;

	},
	
	getChildHeight:function(){
		
		var totalheight = 0;
		var mychildren = $(this.id).childElements();
		for(var i=0;i< mychildren.length;i++){
			if($(mychildren[i].id).visible()){
			totalheight = totalheight + $(mychildren[i].id).getHeight();
			}// end visible.
		}
		
		return totalheight;
	}
	
	
});

// properties are directly passed to `create` method
var Widget = Class.create();

Widget.prototype = {

	/*
	##################################################################
	initialize: this function is called when instantiating this class
	##################################################################
	*/
	initialize: function(obj) {
		for (property in obj){
			this[property] = obj[property];
		}
	
		//add this widget to the array.
		this.arrayindex = this.parent.arrayWidgets.push(this) -1;
		
		//crate these function as event listners so we keep reference to this object.
		this.initDragWidget = this.initDragWidget.bindAsEventListener(this);
		this.dragWidget = this.dragWidget.bindAsEventListener(this);
		this.stopdragWidget = this.stopdragWidget.bindAsEventListener(this);
		this.doColapse = this.doColapse.bindAsEventListener(this);
		this.highlightHeader = this.highlightHeader.bindAsEventListener(this);
		this.removeWidget = this.removeWidget.bindAsEventListener(this);

		
		this.popTab = this.popTab.bindAsEventListener(this);
		this.doGo = this.doGo.bindAsEventListener(this);
		this.helpWindow = this.helpWindow.bindAsEventListener(this);
		
		
		this.draw();
	},
	
	/*
	##################################################################
	Properties: below are various properties we set for the widget
	##################################################################
	*/
	am_id:0, // this is the application id
	
	tab_id:0, //this is the tab this widget is on
	
	parent:'0', // the container name within a tab that this widget is rendered to.
	
	container:'0', //the column div id
	
	ac_id:0, // the container(column) id  this widget is rendered to
	
	ap_id:0, // the id for this widget/plugin
	
	cp_id:0, //customer plugin id
	
	id:'none', // the uniqe name for this widget
	
	title:'DEMO', // - text to display in the header
	
	go_text:'', // - text to display in the popup for the external site
	
	go_url:'', // - the link to generate for the extrenal site
	
	help_url:'', // - the link to generate for the help window	
	
	height:'100px', // - height in px
	
	width:'100%', // - width in px or %
	
	content_url:'', // - url to make ajax call to

	isContentLoaded: false, // did the content load
	
	drag:true, // - can we drag this plugin Y/N
	
	mydelete:true, // can this plugin be delted Note: delete is a javascript keyword thus the mydelete name
	
	forcecontainer:false, // is this plugin limited to movement only in this container?
	
	colapsed:'N', // - did the user colapse this plugin? if so leave it colapsed. 
	
	dragging:false, // are we currently dragging.
	
	mouse_x:0, //mouse x when start dragging
	
	mouse_y:0, //mouse y when start dragging.
	
	dragOffset:'', // coordinates when dragging started. [Number, Number] also accessible as { left: Number, top: Number }
	
	currentOffset:'', //coordinates while dragging [Number, Number] also accessible as { left: Number, top: Number }
	
	arrayindex:0, 
	
	currentdroptarget:'', // the current possible drop target
	
	droptargetinsert:null, //what widget we insert before, if null we append to the end
	
	overtarget:false, // are we curretnly over a target.
	
	currentDragWidth:0, //the current width for a drag over
	
	sortorder: 0, // the current order in the container.
	
	beforearrayIndex: 0,
	
	droparrayIndex: 0,
	
	dragTopBounds: 0, //the calculated top bounds when dragging.
	
	tabset:'', //the tab object we are in so we can pop to a new tab.
	
	holderoffset:0, // the holder's position
	
	/*
	##################################################################
	CSS Properties: these styles can be overridden.
	##################################################################
	*/  	
	maindivCSS:'dragableBoxRSNA', // this is the main box outline and dropshadow
	
	innerdivCSS:'dragableBoxInnerRSNA', // the internal box for content.
	
	headerdivCSS:'dragableBoxHeaderRSNA', // the header
	
	headerdivHighlightCSS:'dragableBoxHeaderHighlight',
	
	holderdivCSS: 'dragHolderDiv',
	
	/*
	##################################################################
	Div Id's - the dom id for the various parts of the widget.
	these will be named automatically in the various draw functions.
	##################################################################
	*/  		
	
	maindivID:'',
	innerdivID:'',
	headerdivID:'',
	titledivID:'',
	statusdivID:'',
	expanddivID:'',
	tabpopdivID:'',
	godivID:'',
	/*
	##################################################################
	Display properties: these styles can be overridden.
	##################################################################
	*/ 	
	
	showHeader:true,
	
	debug:false, // changes output displays for developers 
	
	/*
	##################################################################
	Icon properties: these styles can be overridden.
	##################################################################
	*/	
	
	iconDelete:'iconDelete',
	  
	iconLock:'iconLock',
	
	iconDragAll:'iconDragAll',
	
	iconDragForce:'iconDragForce',
	
	iconLoading:'iconLoading',
	
	iconColapsed:'iconColapsed',
	
	iconExpanded:'iconExpanded',
	
	iconGo:'iconGo',
	
	
	
	/*
	##################################################################
	Methods: things we can do.
	##################################################################
	*/  
	  
	  
	  
	  
	/*
	##################################################################
	DRAWING Methods: rendering and display methods
	##################################################################
	*/  	  
	   

	 
	 // draw - uses the properties to draw the appropriate items to the screen
	 draw: function(){


		
		
		var holderdiv = document.createElement('DIV');
		holderdiv.className = this.holderdivCSS;
		this.holderdivID = 'holderDiv' + this.ap_id;
		holderdiv.id = this.holderdivID;	
		holderdiv.style.display = 'none';
		holderdiv.ap_id = this.ap_id;
		  
		var maindiv = document.createElement('DIV');
		maindiv.className = this.maindivCSS;
		maindiv.style.height = this.height;
		maindiv.style.width = this.width;
		this.maindivID = 'mainDiv' + this.ap_id;
		maindiv.id = this.maindivID;
		maindiv.ap_id = this.ap_id;
		
		var innerdiv = document.createElement('DIV');
		innerdiv.className=this.innerdivCSS;
		this.innerdivID ='innerDiv' + this.ap_id;
		innerdiv.id = this.innerdivID;
			  
		var headerdiv = document.createElement('DIV');
		headerdiv.className = this.headerdivCSS;
		this.headerdivID ='headerDiv' + this.ap_id;
		headerdiv.id = this.headerdivID;
		headerdiv.parent = this;		
		  

		widgetContainer = this.container.getEl();
		widgetContainer.insertBefore(holderdiv,document.getElementById(this.container.footerdivID));
		widgetContainer.insertBefore(maindiv,document.getElementById(this.container.footerdivID));
		

		$(this.maindivID).insert(headerdiv);
		$(this.maindivID).insert(innerdiv);
		//$(this.maindivID).insert(statusdiv);
		
		
		//var innerHeight = $(this.maindivID).getHeight() - ($(this.headerdivID).getHeight() + $(this.statusdivID).getHeight())
		var innerHeight = $(this.maindivID).getHeight() - ($(this.headerdivID).getHeight())
		$(this.innerdivID).setStyle({height: innerHeight + 'px'});
		
		this.drawHeader();

		//this.setTitle(this.title + ' sortorder: ' + this.sortorder);
		var dragOffset = $(this.maindivID).cumulativeOffset();		

		this.droparrayIndex = this.container.addDropTarget(this,this.ap_id);
		
		if(this.drag == 'N' && this.mydelete != 'Y'){
			this.parent.removeDropObject($(this.maindivID).previous(1).id);
			//alert($(this.maindivID).previous(1).id);	
		}
		
		
		
		this.setColapse(false);


	  },
	  
	  
	  
	  /*drawStatus: function(){
		  //draws the status bar
		var tabpopdiv = document.createElement('DIV');
		this.tabpopdivID = 'tabPop' + this.ap_id;
		tabpopdiv.id = this.tabpopdivID;
		tabpopdiv.className = 'iconTabPop';
		$(this.statusdivID).insert(tabpopdiv);
		  
			  
	  },*/
	  
	  
	  // draws the header
	  drawHeader: function(){
		  
		var expanddiv = document.createElement('DIV');
		this.expanddivID = 'expand' + this.ap_id;
		expanddiv.id = this.expanddivID;
		$(this.headerdivID).insert(expanddiv);
		

		
		
		
		if(this.mydelete == 'Y'){
			var closediv = document.createElement('DIV');
			closediv.title = 'Delete this Widget';
			closediv.className = this.iconDelete;
			closediv.onmousedown = this.removeWidget;
			//closediv.parentObj = this;
			$(this.headerdivID).insert(closediv);
			
			
		var tabpopdiv = document.createElement('DIV');
		this.tabpopdivID = 'tabPop' + this.ap_id;
		tabpopdiv.id = this.tabpopdivID;
		tabpopdiv.className = 'iconTabPop';
		tabpopdiv.title ='Open this in a new tab.';
		$(this.headerdivID).insert(tabpopdiv);			
			
		Event.observe(this.tabpopdivID, 'mousedown', this.popTab);	
			
			//div.appendChild(closediv);
		} else {
		
			var lockdiv = document.createElement('DIV');
			lockdiv.className = this.iconLock;
			lockdiv.title = 'This widget cannot be deleted.';
			//div.appendChild(lockdiv);			
			$(this.headerdivID).insert(lockdiv);
		}
		
	
		/*if(this.drag){
			
			var dragdiv = document.createElement('DIV');
			
			if(this.forcecontainer){
				dragdiv.className = this.iconDragForce;
				dragdiv.title = 'You can drag this widget within this column.';
			} else {
				dragdiv.className = this.iconDragAll;	
				dragdiv.title = 'You can drag this widget to any column.';
			}
			
			//div.appendChild(dragdiv);
			$(this.headerdivID).insert(dragdiv);

			
			
		}	*/	
		

		var help_text = 'Information about ';
		if (this.go_text != ''){
			var godiv = document.createElement('DIV');
			this.godivID = 'go' + this.ap_id;
			godiv.id = this.godivID;
			godiv.className = 'iconGo';
			godiv.title = this.go_text;
			$(this.headerdivID).insert(godiv);			
			Event.observe(this.godivID, 'mousedown', this.doGo);	
			help_text = help_text + this.go_text;
		}else{
			help_text = help_text + 'this widget';	
		}
		
		if(this.help_url != ''){
			var helpdiv = document.createElement('DIV');
			this.helpdivID = 'help' + this.ap_id;
			helpdiv.id = this.helpdivID;
			helpdiv.className = 'iconHelp';
			helpdiv.title = help_text;
			$(this.headerdivID).insert(helpdiv);			
			Event.observe(this.helpdivID, 'mousedown', this.helpWindow);			
		}
		
		var titlediv = document.createElement('DIV');
		titlediv.innerHTML = this.title;
		this.titledivID ='titleDiv' + this.ap_id;
		titlediv.id = this.titledivID;
		//titlediv.onmouseover = this.highlightHeader;
		//titlediv.onmouseout = this.highlightHeader;
		
		$(this.headerdivID).insert(titlediv);
		

		
		//$(this.titledivID).parentObj = this;

		//Event.observe(this.titledivID , 'mouseover', this.highlightHeader);
		//Event.observe(this.titledivID , 'mouseout', this.highlightHeader);
		
		
	
		if(this.drag == 'Y'){
			// event listeners can only be addded after the object added to the DOM 
			$(this.titledivID).setStyle({cursor:'move'});
			Event.observe(this.titledivID , 'mousedown', this.initDragWidget);
		} else {
			
			
		}
		
		
		Event.observe(this.expanddivID, 'mousedown', this.doColapse);
		
		return true;
		
	  },
	  
	  
	  doColapse:function(){
		if(this.colapsed == 'Y'){
			this.colapsed = 'N';
		} else {
			this.colapsed = 'Y';	
		}
		
		this.setColapse(true);
		
	  },
	  
	  setColapse:function(doupdate){
		
		
		
		if(this.colapsed == 'Y'){
			
			//var cHeight = ($(this.headerdivID).getHeight() + $(this.statusdivID).getHeight());
			var cHeight = ($(this.headerdivID).getHeight());
			
			$(this.innerdivID).hide();
			$(this.maindivID).setStyle({width:  $(this.maindivID).getStyle('width'), height: cHeight + 'px'});
			$(this.holderdivID).setStyle({width:  $(this.maindivID).getStyle('width'), height: cHeight + 'px'});
			$(this.expanddivID).className = this.iconColapsed;
			$(this.expanddivID).title = 'Expand this widget.';
			
		} else {
			$(this.innerdivID).show();
			//var cHeight = ($(this.headerdivID).getHeight() + $(this.statusdivID).getHeight() + $(this.innerdivID).getHeight());
			var cHeight = ($(this.headerdivID).getHeight() +  $(this.innerdivID).getHeight());
			$(this.maindivID).setStyle({width: $(this.maindivID).getStyle('width'), height: cHeight + 'px'});
			$(this.holderdivID).setStyle({width: $(this.maindivID).getStyle('width'), height: cHeight + 'px'});
			$(this.expanddivID).className = this.iconExpanded;
			$(this.expanddivID).title = 'Collapse this widget.';
			
			if(! this.isContentLoaded){
				this.loadContent();
			}
			
			this.parent.adjustHeight();
			
		}
		
		
		if(doupdate){
			Ext.Ajax.request({
				url:'update_widget_colapsed.cfm'
				,params:{cp_id:this.cp_id,colapse:this.colapsed}
				,method:'GET'
				,success:function(responseObj,optionsObj){
				}
				,failure:function(responseObj,optionsObj){
				}
			});			
		}
		
		
	  },
	  
	  loadContent: function(){
		  
		 
		  var widget = this;
		  var url = widget.content_url;
		  $(widget.innerdivID).innerHTML = '<img src="'+ myRSNApath + 'images/indicator.gif" /> Loading ';
		  
		$(widget.innerdivID).innerHTML =  $(widget.innerdivID).innerHTML + '.';
		
		Ext.Ajax.request({
			url:url
			,params:{cp_id:this.cp_id,colapse:this.colapsed}
			,method:'GET'
			,success:function(responseObj,optionsObj){
				 $(widget.innerdivID).innerHTML = responseObj.responseText;
				 executeJavascript($(widget.innerdivID).id);
				 widget.isContentLoaded = true;
			}
			,failure:function(responseObj,optionsObj){
				 if(widget.debug){
					$(widget.innerdivID).innerHTML = responseObj.responseText;	  
				 } else {
					$(widget.innerdivID).innerHTML = 'Could not load content.'; 
				 }
			}
		});	
		  
	  },
	  
	  
	  
	  setDrag: function(value){
		if(value == true || value == 'Y'){
			this.drag=true;
		}else {
			this.drag=false;
		}
	  },
	  
	  removeWidget: function(){
		
		var removeObject = this;
		var removediv = $(removeObject.maindivID);
		var removedrop = 'dropDiv_' + removeObject.id;
		
		Ext.Msg.show({
		title: 'Confirm',
		msg: 'Are you sure you want to remove this widget?',
		minWidth:250,
		buttons: Ext.MessageBox.YESNO,
		fn: function(btn){
				if(btn=='yes'){
					Ext.Ajax.request({
						url:'delete_customer_plugin.cfm'
						,method:'GET'
						,params:{cp_id:removeObject.cp_id}
						,success:function(responseObj,optionsObj){
							removediv.parentNode.removeChild(removediv);
							removeObject.parent.arrayWidgets.splice(removeObject.arrayindex,1);
							removeObject.parent.removeDropObject(removedrop);
							removeObject.parent.resetDropObjects();
						}
						,failure:function(form, action){ 
							Ext.Msg.show({
								title: 'ERROR',
								msg: 'This widget cannot be removed at this time.',
								minWidth:200,
								buttons: 'Ext.MessageBox.OK'
							});
						}
					});
				    
				} //'yes'
			}
		});
		
		

		  
		  
	  },
	  
	  highlightHeader: function(){
		  //alert(this.className);
		  if($(this.headerdivID).className == this.headerdivHighlightCSS){
			   $(this.headerdivID).className = this.headerdivCSS;
		  }else{
			  $(this.headerdivID).className = this.headerdivHighlightCSS;
		  }
		//alert(this.parentObj.id);  
		  
	  },
	  
	  
	getLeftPos:function(){

	  		return $(this.maindivID).viewportOffset().left

		
	},
	  
	  
	getTopPos:function()
	{	

	  return $(this.maindivID).viewportOffset().top
	},
	
	getWidth:function()
	{
		return $(this.maindivID).getWidth();
		//return 	document.getElementById(this.maindivID).offsetWidth;
		
	},
	
	getHeight:function()
	{
		return 	$(this.maindivID).getHeight();
		
	},	
	


	
	getNextSibling: function(){
		
		return this.getEl().nextSibling.id
		
	},
	
	getParentNode: function(){
		
		return this.getEl().parentNode.id
		
	},
	
	setDragWidth:function(w){
		
		if(this.currentDragWidth != w){
				$(this.maindivID).setStyle({width:w});
				
				this.currentDragWidth = w;
		}
	},
	
		  
	initDragWidget: function(event){
		
		//get the current mouse coordinates
		this.mouse_x = event.pointerX();
		this.mouse_y = event.pointerY();
		
		//get the top and left
		//this.dragOffset = $(this.maindivID).cumulativeOffset();	
		
		
		//bump up the z-index to put widget on top
		$(this.maindivID).setStyle({zIndex:100});
		//make position absoulte
		$(this.maindivID).absolutize();
		//save the original height and width
		this.el_width = $(this.maindivID).getStyle('width');
		//this.el_height = $(this.maindivID).getStyle('height');
		this.el_height = $(this.maindivID).getHeight();

		//set the drag width to the current width.. this will change as we move over drop targets.
		this.setDragWidth(this.el_width);
		
		

		// we need to tell the parent that this widget in the array is being modified/dragged.
		this.parent.draggingWidget = this.arrayindex;
		
		//now calculate parent offsets and store so we do not have to calculate as we drag the widget.
		//this.parent.parentPosition = $(this.parent.id).cumulativeOffset();		
		//this.parent.parentScrollOffset = $(this.parent.id).cumulativeScrollOffset();
		this.parent.parentDimensions = $(this.container.id).getDimensions();
		//this.parent.scrollHeight = $(this.parent.id).scrollHeight;	
		//show the holder div.. and make sure the widget is still displayed above it.
		
		$(this.holderdivID).show();
		$(this.holderdivID).setStyle({position:'static'});
		
		//$(this.holderdivID).innerHTML = 't: ' + $(this.holderdivID).cumulativeOffset().top + ' l: ' + $(this.holderdivID).cumulativeOffset().left;
		//$(this.headerdivID).style.className= this.headerdivHighlightCSS;
		/*if(isIE){
			$(this.maindivID).clonePosition(this.holderdivID,{offsetTop:this.parent.parentScrollOffset.top});
		}else{
			$(this.maindivID).clonePosition(this.holderdivID)
		}*/
		//$(this.parent.id).scrollTop = this.parent.parentScrollOffset.top;
		//set the coordinates of the drop objects.
		this.parent.resetDropObjects();
		

		
		
		//this.setTitle(' top: ' + this.dragOffset.top + ' left: ' + this.dragOffset.left + ' pt: ' + this.parent.parentPosition.top  + ' sot: ' +  $(this.parent.id).cumulativeScrollOffset().top);
		
		//set up the mousemove and up events
		Event.observe(document, 'mousemove', this.dragWidget);
		Event.observe(document, 'mouseup', this.stopdragWidget);
		
		//these are set to prevent text selecting as you move the mouse
		document.onselectstart = function () { return false; };
		document.onmousedown = function () { return false; };
	
		document.body.style.cursor = 'move';
		document.body.appendChild($(this.maindivID));
		
		this.holderoffset = $(this.holderdivID).cumulativeOffset();
		
		this.setElPosition(this.maindivID,this.holderoffset.left,this.holderoffset.top);
		//this.setTitle(' top: ' + this.holderoffset.top + ' left: ' + this.holderoffset.left);
		
		//alert(this.container.getChildHeight());
		
		
		return false;		
		 
	 },
	 
	 dragWidget:function(event){
			//dragObject = this;
			this.overtarget = false;
			this.parent.dragging = true;
			
			this.currentOffset = $(this.maindivID).cumulativeOffset();
			
			this.top = event.pointerY() - (this.mouse_y - this.holderoffset.top);
			this.left = event.pointerX() - this.mouse_x + this.holderoffset.left;
			
			
			//determine when and if we need to scroll the div tag we are in. 
			//screem bottom bounds.. when the bottom of the widget hits this mark we need to scroll the window
				
			
			
			var scrollTop =  document.viewport.getScrollOffsets().top;
			var docHeight = document.viewport.getHeight();
			
			var sbb = scrollTop + docHeight;
			var wb = this.currentOffset.top + this.el_height;
			
			this.setElPosition(this.maindivID,this.left,this.top);
			//this.setTitle('top: ' + this.top + ' left: ' + this.left + ' scrolltop: ' + scrollTop + ' sbb: ' + sbb + ' wb: ' + wb + ' ph: ' + this.parent.parentDimensions.height);
			
			if(wb > sbb){
				//the widget has reached the bottom of the parent div.. scroll id(sbb/10) + scrollTop;
				 window.scrollTo(0, scrollTop + 10);
				
			}
			
			//if we are scrolled then we need to move the div tag up
			//var stb = this.parent.parentPosition.top + scrollTop;
			if(scrollTop > 0 && this.top < scrollTop){
				window.scrollTo(0, scrollTop - 10);
				
			}			
			
			

			
			
			
			// loop through the drop targets and see if we are over one
			for(var i=0;i< this.parent.arrayDropTargets.length;i++){
				
				if(
			   
			   (
			   ((this.left > this.parent.arrayDropTargets[i].left && 
				this.left <  this.parent.arrayDropTargets[i].right) && 
			   (this.top > this.parent.arrayDropTargets[i].top && 
				this.top < this.parent.arrayDropTargets[i].bottom)) 
			   
			 /* || OPTIONAL PART OF IF STATEMENT, TO UTILIZE RIGHT BOUNDING.
			   
			   (
				 (
				  this.right <  arrayDropTargets[i].right
				 &&
				 this.right > arrayDropTargets[i].left
				 )
				 && 
			   (this.top > arrayDropTargets[i].top && 
				this.top < arrayDropTargets[i].bottom) 
				
				)*/
			   )
			   
			   && 
			   (this.parent.arrayDropTargets[i].ap_id != this.ap_id))
			{
				if( this.currentdroptarget != this.parent.arrayDropTargets[i].id){
						if(this.currentdroptarget != ''){
							olddrop = this.parent.getDropIndexByName(this.currentdroptarget);
							this.parent.resizeDropObject(olddrop);
							this.parent.setDropRange(olddrop);
						}// end arrayRSNAWidgets[draggingWidget].currentdroptarget
										
					this.currentdroptarget = this.parent.arrayDropTargets[i].id;
					this.parent.arrayDropTargets[i].style.height = this.getHeight() + 'px';
					this.parent.setDropRange(i);
					this.parent.arrayDropTargets[i].style.display = '';
					
					if(this.parent.arrayDropTargets[i].nextSibling != undefined){
						//arrayRSNAWidgets[draggingWidget].setTitle('nexsibling: ' + arrayDropTargets[i].nextSibling.id);
						this.droptargetinsert = this.parent.arrayDropTargets[i].nextSibling;
					}else {
						//arrayRSNAWidgets[draggingWidget].setTitle('nexsibling: null');
						this.droptargetinsert = null;
						
					}

					// reset the bottom area when dragging over
					//arrayDropTargets[i].bottom = (getAbsoluteTop(arrayDropTargets[i].id) + document.getElementById(arrayDropTargets[i].id).offsetHeight);
					//alert(this.parent.arrayDropTargets[i].offsetWidth);
					this.setDragWidth(this.parent.arrayDropTargets[i].offsetWidth + 'px');

					
				}// end arrayRSNAWidgets[draggingWidget].currentdroptarget != arrayDropTargets[i].id
				this.overtarget = true;
				break;
			}
			
			
			// end if
			
		}// end foR	
				
		
		
		
		if(!this.overtarget && this.currentdroptarget != ''){
			
			olddrop = this.parent.getDropIndexByName(this.currentdroptarget);
			
			
			this.parent.resizeDropObject(olddrop);
			this.parent.setDropRange(olddrop);
			//this.parent.arrayDropTargets[olddrop].style.display = 'none';
			this.currentdroptarget = '';
			
		}
		
		

		
		},
	 
	
	
	stopdragWidget:function(e){
		
	
		
		Event.stopObserving(document, 'mousemove', this.dragWidget);
		Event.stopObserving(document, 'mouseup', this.stopdragWidget);
		
		
	
		

	

		document.onselectstart = null;
		document.onmousedown =  null;
		
		document.body.style.cursor = '';
		
		
		
		dragObject = this;
		dragObject.getEl().style.zIndex = 1;
		$(dragObject.headerdivID).style.className= this.headerdiv;

		//where are we dropping this widget
		dropObject = document.getElementById(dragObject.currentdroptarget);
		
		if(dragObject.overtarget && (!this.forcecontainer || this.droptargetinsert.id.substr(2) == this.container.id)){
			
			if(dragObject.droparrayIndex >= this.parent.arrayDropTargets.length){
				dragObject.droparrayIndex = this.parent.arrayDropTargets.length-1;	
			}
			

//this.container.addDropTarget(this,this.ap_id)
			dropObject.style.height = this.parent.arrayDropTargets[dragObject.droparrayIndex].classHeight + 'px';
		
			//move the holder div
			dropObject.parentNode.insertBefore(document.getElementById(dragObject.holderdivID),dragObject.droptargetinsert);
			dragObject.setElSize(dragObject.holderdivID,dragObject.getWidth(),dragObject.getHeight());
			
			$(dragObject.holderdivID).setStyle({position:'static'});
			document.getElementById(dragObject.holderdivID).style.display = 'none';
			//$(dragObject.holderdivID).toggle();
			
			//document.getElementById(dragObject.holderdivID).style.position = 'static';		
			//document.getElementById(dragObject.holderdivID).style.display = 'none';
			
			dropObject.parentNode.insertBefore(dragObject.getEl(),dragObject.droptargetinsert);
			
			//dragObject.getEl().style.position = 'static';
			$(dragObject.maindivID).setStyle({position:'static'});

			
			dropDiv = dragObject.parent.arrayDropTargets[dragObject.droparrayIndex]
			
			
			dropObject.parentNode.insertBefore(dropDiv,dragObject.droptargetinsert);
			// if we are in a new container we need to update
			var current_container_id = $(dragObject.maindivID).parentNode.id;
			if(current_container_id != dragObject.container.id){
				//alert(dragObject.parent.getContainerById(current_container_id).ac_id+  ' dc: ' + dragObject.container.id);
				dragObject.container = dragObject.parent.getContainerById(current_container_id);
				
				
			}
			dragObject.parent.updateSortOrder();
			dragObject.parent.adjustHeight();
			
		} else {
		
			//append back to the column
			//container
			//$(dragObject.container.id).insert($(dragObject.maindivID));
			$(dragObject.holderdivID).insert({before:$(dragObject.maindivID)});
			
			
			$(dragObject.maindivID).setStyle({position:'static'});
			$(dragObject.maindivID).clonePosition(dragObject.holderdivID);
			$(dragObject.holderdivID).hide();
			
			

			

		}
		dragObject.parent.resetDropObjects();
		//document.getElementById(dragObject.holderdivID).style.display = 'none';
		//dropObject.style.display = 'none';
		dragObject.currentdroptarget = ''
		dragObject.parent.draggingWidget = -1
		dragObject.parent.dragging = false;
		//$(dragObject.headerdivID).style.className = dragObject.headerdivCSS;
		
		
		
	},
	
	getEl:function(){
		return document.getElementById(this.maindivID);	
	},
		  
	setElSize: function(id,w,h){
		el = document.getElementById(id);
		el.style.width = w + 'px';
		el.style.height = h + 'px';
		
	},
	
	setElPosition: function(id,l,t){
		//el = document.getElementById(id);
		//el.style.top = top + 'px';
		//el.style.left = left + 'px';
		
		$(id).setStyle({top:t + 'px',left:l + 'px'});
		
		
	},
	  

	  

	setTitle: function(title){
			document.getElementById(this.titledivID).innerHTML = title;
			this.title = title;
		
	},
		  
	 
	doGo : function(){
		launchExtWindow(this.go_url,this.go_text,600,800);
		
	},
	
	helpWindow : function(){
		launchExtWindow(this.help_url,this.title + ' Information',250,500);
	},	
	 
	 
    popTab: function(){
	   if(this.tabset.findById('tab_' + this.ap_id) == null){
			var removeObject = this;
			var removediv = $(removeObject.maindivID);
			var removedrop = 'dropDiv_' + removeObject.id;
			// new - remove the widget from the dashboard since we have advanced drag an drop featrues that can be hard to maintain.
			  
			Ext.Ajax.request({
					url:'update_customer_tab.cfm'
					,method:'GET'
					,params:{ap_id:this.ap_id}
					,success:function(responseObj,optionsObj){
						eval(responseObj.responseText);
						Ext.Ajax.request({
								url:'delete_customer_plugin.cfm'
								,method:'GET'
								,params:{cp_id:removeObject.cp_id}
								,success:function(responseObj,optionsObj){
										removediv.parentNode.removeChild(removediv);
										removeObject.parent.arrayWidgets.splice(removeObject.arrayindex,1);
										removeObject.parent.removeDropObject(removedrop);
										removeObject.parent.resetDropObjects();
									}
								,failure:function(responseObj,optionsObj){
								}
							});	
					}
					,failure:function(responseObj,optionsObj){
					}
				});	
	   }
	  this.tabset.setActiveTab('tab_' + this.ap_id);
    }	// end popTab 
}