
var windowState = {
	minimized: 0,
	normal: 1,
	maximized: 2,
	shaded: 3
};

var windowStyle = {
	canvas: 0,
	popup: 	1,
	pane: 	2
};

var windowPositioning = {
	absolute: 	'a',
	relative: 	'r',
	floatLeft: 	'fl',
	floatRight:	'fr'
};

var windowSizing = {
	manual: 	'',
	fill: 		'f',
	fillHoriz: 	'fh',
	fillVert: 	'fv'
};

var windowSecurity = {
	unsecured : 0,
	saveState : 1,
	secured :	2
}

var windowResizeFunctions = {
	topLeft : function(){

		var diffX = dh.mouseX - client.resizeStartPos[0];
		var diffY = dh.mouseY - client.resizeStartPos[1];

		var newX = client.resizeStartPos[0] + diffX;
		var newY = client.resizeStartPos[1] + diffY;
		var newW = client.resizeStartSize[0] - diffX;
		var newH = client.resizeStartSize[1] - diffY;

		if( newW < client.resizeMinSize[0] ){
			newW = client.resizeMinSize[0];
			newX = client.resizeStartPos[0] + ( client.resizeStartSize[0] - client.resizeMinSize[0]);
		}
		if( newH < client.resizeMinSize[1] ){
			newH = client.resizeMinSize[1];
			newY = client.resizeStartPos[1] + ( client.resizeStartSize[1] - client.resizeMinSize[1]);
		}

		dh.nodes.resizeAnimation.moveTo( newX,  newY );
		dh.nodes.resizeAnimation.resizeTo(	newW, newH );

		},
	top : function(){
		var diffY = ( dh.mouseY - client.resizeStartPos[1]);
		var newY = client.resizeStartPos[1] + diffY;
		var newH = client.resizeStartSize[1] - diffY;

		if( newH < client.resizeMinSize[1] ){
			newH = client.resizeMinSize[1];
			newY = client.resizeStartPos[1] + ( client.resizeStartSize[1] - client.resizeMinSize[1]);
		}

		dh.nodes.resizeAnimation.Y(	newY );
		dh.nodes.resizeAnimation.H(	newH );
		},
	topRight : function(){
		var diffY = ( dh.mouseY - client.resizeStartPos[1]);
		var newY = client.resizeStartPos[1] + diffY;
		var newH = client.resizeStartSize[1] - diffY;
		var newW = dh.mouseX - dh.nodes.resizeAnimation.x

		if( newH < client.resizeMinSize[1] ){
			newH = client.resizeMinSize[1];
			newY = client.resizeStartPos[1] + ( client.resizeStartSize[1] - client.resizeMinSize[1]);
		}
		if( newW < client.resizeMinSize[0] ) newW = client.resizeMinSize[0];

		dh.nodes.resizeAnimation.Y(	newY );
		dh.nodes.resizeAnimation.H(	newH );
		dh.nodes.resizeAnimation.W( newW );
	},
	right : function(){
		var newW = dh.mouseX - dh.nodes.resizeAnimation.x
		if( newW < client.resizeMinSize[0] ) newW = client.resizeMinSize[0];
		dh.nodes.resizeAnimation.W( newW );
		},
	bottomRight : function(){
		var newW = dh.mouseX - dh.nodes.resizeAnimation.x
		var newH = dh.mouseY - dh.nodes.resizeAnimation.y

		if( newW < client.resizeMinSize[0] ) newW = client.resizeMinSize[0];
		if( newH < client.resizeMinSize[1] ) newH = client.resizeMinSize[1];

		dh.nodes.resizeAnimation.W( newW );
		dh.nodes.resizeAnimation.H( newH );
		},
	bottom : function(){
		var newH = dh.mouseY - dh.nodes.resizeAnimation.y
		if( newH < client.resizeMinSize[1] ) newH = client.resizeMinSize[1];
		dh.nodes.resizeAnimation.H( newH );
		},
	bottomLeft : function(){
		var diffX = dh.mouseX - client.resizeStartPos[0];
		var newX = client.resizeStartPos[0] + diffX;
		var newW = client.resizeStartSize[0] - diffX;
		var newH = dh.mouseY - dh.nodes.resizeAnimation.y

		if( newW < client.resizeMinSize[0] ){
			newW = client.resizeMinSize[0];
			newX = client.resizeStartPos[0] + ( client.resizeStartSize[0] - client.resizeMinSize[0]);
		}
		if( newH < client.resizeMinSize[1] ) newH = client.resizeMinSize[1];

		dh.nodes.resizeAnimation.X(	newX );
		dh.nodes.resizeAnimation.W(	newW );
		dh.nodes.resizeAnimation.H( newH );
		},
	left: function(){
		var diffX = dh.mouseX - client.resizeStartPos[0];
		var newX = client.resizeStartPos[0] + diffX;
		var newW = client.resizeStartSize[0] - diffX;
		if( newW < client.resizeMinSize[0] ){
			newW = client.resizeMinSize[0];
			newX = client.resizeStartPos[0] + ( client.resizeStartSize[0] - client.resizeMinSize[0]);
		}
		dh.nodes.resizeAnimation.X(	newX );
		dh.nodes.resizeAnimation.W(	newW );
	}
};
//*************************************************************************
//
//  Generate a DHTML window, controlled by dhtml.js
//
//	settings object may contain and does not require settings for the following values
//
//	startingPosition : 	[x,y]
//	startingState:		windowState.blah
//	windowStyle:		windowStyle.blah
//	windowPositioning:	windowPositioning.blah
//	windowSizing:		windowSizing.blah
//	closeButton:		boolean
//  draggable:			boolean
//	fadeInOut:			boolean
//  maximizeButton:		boolean
//	minimizeButton:		boolean
//  resizable:			boolean
//  shadeButton:		boolean
//  showIcon:			boolean
//  showTitle:			boolean
//	showTabs:			boolean
//  showStatus:			boolean
//
//*************************************************************************
function DHWindow( windowID, settingsObject, windowParent, windowTitle ){
	this.id = windowID;

	this.tabs = [];

	this.readSettings( settingsObject );

	//backwards compatability until all windows are using the settings storage
	if(windowTitle != dhNull) this.windowTitle = windowTitle;

	if( !this.windowExists() ) {
		//console.log( "building " + windowID);
		this.createWindow(windowParent, windowTitle);
	} else {
		//console.log( "inserting " + windowID);
		setParent( getObject("dhWin_" + this.id) , windowParent );
		this.addOptionalElements();
	}

	//either the windows exists or just got created, so lets add  the dhtml objects
	this.addObjects();

	this.initObjects();

	if(this.draggable){
		this.windowNode.draggable = true;
		this.titleBar.draggable = 	true;
		this.windowNode.setHandle(this.titleBar );
	}

	//this should eventually be written into DHTML maybe
	this.windowNode.window = this;

//	if( startingPosition ){
//		this.windowNode.moveTo( settingsObject.startingPosition[0], settingsObject.startingPosition[1] );
//	}

	var windowMemory = client.rememberWindow( this.id );
	if( windowMemory ){
		this.windowNode.moveTo( windowMemory.x, windowMemory.y );
		this.x = windowMemory.x;
		this.y = windowMemory.y;
		this.windowNode.resizeTo( windowMemory.w, windowMemory.h );
		if(parseInt(windowMemory.helpVisible)){
			this.helpCanvas.show();
		} else {
			this.helpCanvas.hide();
		}

		//window state needs to be added in here i believe.
	}

	client.addHelpBeacon( 'community', this.windowNode.obj, this.id);

	// this shoudl already be set by now maybe?
	if( settingsObject.startingState != dhNull) {
		switch( settingsObject.startingState ){
			case windowState.maximized:
				this.__maximize();
				break;
			case windowState.minimized:
				//need some info to restore properly - before the hideNow only,
				//hide now conains block none
				this.normalSize = [this.windowNode.w , this.windowNode.h ];
				this.hideNow();		// POOF!
				this.windowState = windowState.minimized;
				break;
			case windowState.normal:
				this.showNow();
				//this.restore();
				break;
			default:
				//hmm
				break;
		}
	}

	this.statusAd = createObject("div", "dhWin_"+this.id+"_StatusAd", "windowAdUrl", this.statusBar.obj, '');

}

DHWindow.prototype = {
	//-----------------------------
	// Window Element Refrences
	//-----------------------------
		id:				"",
		dhNode:			null,
		windowNode: 	null,
		dropShadow: 	null,
		bg1:			null,
		bg2:  			null,
		canvas:			null,
		loader:			null,
		canvas: 		null,
		titleBar: 		null,
		tabBar: 		null,
		tabBarCanvas:	null,
		statusBar:		null,
		selectedTabKey: null,
		selectedTab:	null,

	//----------------------------
	// Window Events
	//----------------------------
		onGrab: 	null,
		onDrop: 	null,
		onOk: 		null,
		onCancel: 	null,
		onLoad:		null,
		onClose: 	null,
		onShow: 	null,
		onHide: 	null,
		onResize: 	null,
		onMinimize: null,
		onMaximize: null,
		onRestore: 	null,
		onTab: 		null,

	//----------------------------
	// Window Properties
	//----------------------------
		fadeIn:	  			false,
		fadeOut:	  		false,
		initialized:		false,
		useWindowProcessor: false,
		requiresLogin:		false,
		minimizeTo:			null, 					//an element to minimize in to and out of
		w: 					null,
		h: 					null,
		x: 					null,
		y: 					null,
		currentCanvas:		null,
		lastWindowState: 	windowState.normal,
		windowState: 		windowState.normal,
		windowStyle: 		windowStyle.popup,
		tabCount:			0,
		normalSize:  		[ -1 , -1],
		normalPosition:	 	[ -1 , -1],
		centerOnShow:		false,
		resizable: 			false,
		visible: 			false,
		draggable:			null,
		iconVisible:		null,
		titleVisible:		null,
		tabsVisible:		null,
		statusVisible:		null,
		windowPositioning:	null,

	//----------------------------
	// Window Methods
	//----------------------------
		invoke : function(ev, params){
			try { return this['on' + ev](params); }
			catch (ex){  } return true;
		},
		windowExists: function (){
			return ( getObject("dhWin_" + this.id) );
		},

		readSettings : function ( settingsObject ){

			/**
			 * example settings object, with defaults
			 *
			 * 	{
			 * 		secured	:			true,
			 * 		title :				some string,
			 * 		windowStyle :		windowStyle.popup,
			 * 		windowSizing :		windowSizing.manual,
			 * 		windowPositioning : windowPositioning.absolute,
			 * 		startingState :		windowStates.something,
			 * 		startingPosition :	startingPosition,
			 * 		startingSize:		[w,h], <-not used yet
			 * 		minimumSize:		[w,h],
			 * 		centerOnShow :		false,
			 * 		fadeIn :			false,
			 * 		fadeOut :			false,
			 * 		draggable :			true,
			 * 		resizable :			true,
			 * 		showIcon :			false,
			 *		showTitle :			true,
			 * 		showTabs :			false,
			 *		showStatus :		true,
			 * 		minimizeButton :	false,
			 * 		helpButton :		false,
			 * 		reloadButton :		false,
			 * 		rollupButton :		false,
			 * 		closeButton :		false
			 * 		flapCaption:		"",
			 * 		helpVisible:		false,
			 * 		helpText :			""
			 * 	}
			 *
			 */

			

			//if no settings were passed we can atleast try the settings storage
			if( !settingsObject ) settingsObject = client.windowSettings[ this.id ];

			//if we still have nothing then exit
			if( !settingsObject ) return;

			//Read the settings
			//this.useWindowProcessor = (settingsObject.useWindowProcessor != dhNull) ? settingsObject.useWindowProcessor : false;
			this.securityLevel = this.getIntegerSettingValue(settingsObject.securityLevel, 			0);
			if(settingsObject.title ) this.windowTitle = settingsObject.title;
			if(settingsObject.windowStyle != dhNull){ this.windowStyle = parseInt(settingsObject.windowStyle); }
			this.popupPrefix = 		(this.windowStyle == windowStyle.popup )? 	"popup_": "";

			this.windowPositioning = 	this.getStringSettingValue(settingsObject.windowPositioning, 	windowPositioning.absolute);
			this.windowSizing = 		this.getStringSettingValue(settingsObject.windowSizing, 		windowSizing.manual);
			this.startingState = 		this.getStringSettingValue(settingsObject.startingState,		windowState.normal);
			this.startingPosition = 	this.getStringSettingValue(settingsObject.startingPosition, 	false);

			this.draggable = 		this.getBooleanSettingValue(settingsObject.draggable,			true);
			this.resizable = 		this.getBooleanSettingValue(settingsObject.resizable,			true);
			this.minW = 			this.getIntegerSettingValue(settingsObject.minW, 				300);
			this.minH = 			this.getIntegerSettingValue(settingsObject.minH, 				200);

			this.alwaysOnTop = 		this.getBooleanSettingValue(settingsObject.alwaysOnTop,			false);
			this.centerOnShow = 	this.getBooleanSettingValue(settingsObject.centerOnShow,		false);
			this.fadeIn = 			this.getBooleanSettingValue(settingsObject.fadeIn,				"");
			this.fadeOut = 			this.getBooleanSettingValue(settingsObject.fadeOut,				"");

			this.iconVisible = 		this.getBooleanSettingValue(settingsObject.showIcon,			false);
			this.tabsVisible = 		this.getBooleanSettingValue(settingsObject.showTabs,			false);
			this.titleVisible = 	this.getBooleanSettingValue(settingsObject.showTitle,			true);
			this.statusVisible = 	this.getBooleanSettingValue(settingsObject.showStatus,			true);

			//this.shadeButton = 		this.getBooleanSettingValue(settingsObject.shadeButton,		true);
			this.helpButton = 		this.getBooleanSettingValue(settingsObject.helpButton,			false);
			this.reloadButton = 	this.getBooleanSettingValue(settingsObject.reloadButton,		false);
			this.maximizeButton = 	this.getBooleanSettingValue(settingsObject.maximizeButton,		( this.windowStyle == windowStyle.popup ) ? true : false);
			this.closeButton = 		this.getBooleanSettingValue(settingsObject.closeButton,			( this.windowStyle == windowStyle.popup ) ? true : false);

			this.flapCaption =		this.getStringSettingValue(settingsObject.flapCaption, 			"");
			this.helpVisible =		this.getBooleanSettingValue(settingsObject.helpVisible,			true);
			this.helpText =			this.getStringSettingValue(settingsObject.helpText,				"");
		},

		//read a bool settings Value
		getBooleanSettingValue : function( value, defaultVaule ){
			//no vaule? try a defult?
			if( isEmpty(value) ) {
				if( !defaultVaule ) return false;
				else return defaultVaule;
			}
			if( typeof(value) == 'string' ){ return (parseInt(value) == 0) ? false : true; }
			else return (value);
		},

		//read an int settings Value (0 by default)
		getIntegerSettingValue : function( value, defaultVaule ){
			//no vaule? try a defult?
			if( isEmpty(value) ) {
				if( !defaultVaule ) return 0;
				else return defaultVaule;
			}
			value = parseInt(value);
			if( typeof(value) == 'number' ){ return value; }
			else return 0;
		},

		//read a string settings Value ( "" by default )
		getStringSettingValue : function( value, defaultVaule ){
			//no vaule? try a defult?
			if( isEmpty(value) ) {
				if( !defaultVaule ) return "";
				else return defaultVaule;
			}
			if( typeof(value) == 'string' ){ return value; }
			else return "";
		},

		saveUserSettings : function ( forceType ){

			//some vaules are used both before and after the post, these are read
			//before any processing occurs. this way all the vaules will match
			//during execution on this stack.
			var layer = client.currentLayer;
			var thisSpace = this;

			//settings only get saved on webtop and if we're logged in,
			// exit if either of those are wrong.
			if(
				layer == 'contests' ||
				layer == 'cirkitvision' ||
				layer == 'contest_profile' ||
				client.isLoggedIn() == false ||
				this.useWindowProcessor == false
			  )
			  return;
			 //thats a weird way to read it

			if( this.securityLevel > windowSecurity.unsecured ){
				ajax.post(
					'/api/processors/windowProcessor',
					{
						type : ((forceType != dhNull ) ? forceType : 'setUserWindowValues'),
						window_id : this.id,
						visibility: (this.visible) ? 1 : 0,
						x: this.windowNode.x,
						y: this.windowNode.y,
						w: this.windowNode.w,
						h: this.windowNode.h,
						helpVisible: ((this.helpCanvas && this.helpCanvas.visible) ? 1 : 0),
						layerName: layer,
						windowState: this.windowState
					},
					function ( connectionInstance ){ //success
						if( connectionInstance.responseObject ){
							var dataObject = false;

							if( layer == 'community' ) dataObject = client.communityMemory;
							if( layer == 'webtop' ) dataObject = client.webtopMemory;
							if( !dataObject ) return;

							dataObject[ connectionInstance.requestObject.window_id ] = connectionInstance.responseObject;

							if (forceType && forceType == 'setWindowOpen'){
								var data = dataObject[ connectionInstance.requestObject.window_id ];
								setAdBackground(thisSpace.id, data.ad_advertiser_id, data.ad_image_name, data.opacity, data.x_position, data.y_position);
								setAdWindowTitle(thisSpace.id, data.advertiser_name);
								setAdWindowHyperLink(thisSpace.id, data.ad_url, data.ad_url_text);
							}
						}
					},
					function ( connectionInstance ){ //error
						//client.userError("Server Error", "Could not save window size, window settings will not be saved for 1 minute.");
						//TODO
					}
				);
			}
		},



		createWindow: function(parentElement ){
			

			var myID = this.id; 	//for anonymous functions

			//--------------------------
			//these settings needs to be read first, some other settings depend on this flag
			//--------------------------

			//pick a CSS class to apply to the window element, for theme related styles.
			var styleClass = 		(this.windowStyle == windowStyle.popup) ?
										'popupWindow' :
										(this.windowStyle == windowStyle.pane) ?
											'paneWindow' :
											'canvasWindow';

			//--------------
			// Window Basics
			//--------------
			var tmpWindow = 	createObject("div", "dhWin_" + this.id,  						"dhWindow " + this.windowPositioning + " " + this.windowSizing + " " + styleClass, parentElement);

			var tmpShadow = 	createObject("div", "dhWin_" + this.id + "_dropShadow", 		"a dropShadow", 	tmpWindow);
			var tmpBg1 =		createObject("div", "dhWin_" + this.id + "_bg1", 				"a window_bg",		tmpWindow);
			var tmpBg2 =		createObject("div", "dhWin_" + this.id + "_bg2", 				"a window_bg2", 	tmpWindow);
			var tmpBorder =		createObject("div", "dhWin_" + this.id + "_border", 			"a o f window_border",	tmpWindow);
			tmpBorder.innerHTML =	'<div class="a highZ tl 	borderCorner 	borderTL" 	id="dhWin_'+ this.id +'_borderTL"></div>' +
									'<div class="a highZ top 	borderHoriz 	borderT" 	id="dhWin_'+ this.id +'_borderT"></div>' +
									'<div class="a highZ tr 	borderCorner 	borderTR" 	id="dhWin_'+ this.id +'_borderTR"></div>' +
									'<div class="a highZ right 	borderVert 		borderR" 	id="dhWin_'+ this.id +'_borderR"></div>' +
									'<div class="a highZ br 	borderCorner 	borderBR" 	id="dhWin_'+ this.id +'_borderBR"></div>' +
									'<div class="a highZ bottom borderHoriz 	borderB"	id="dhWin_'+ this.id +'_borderB"></div>' +
									'<div class="a highZ bl 	borderCorner 	borderBL" 	id="dhWin_'+ this.id +'_borderBL"></div>' +
									'<div class="a highZ left 	borderVert 		borderL" 	id="dhWin_'+ this.id +'_borderL"></div>';

			var tmpLoader =		createObject("div", "dhWin_" + this.id + "_loader",				"a windowLoader", 	tmpWindow);
			var tmpCanvas = 	createObject("div", "dhWin_" + this.id + "_canvas", 			"a window_canvas",	tmpWindow);

			var html = '<div class="r fh tac">'+this.windowTitle + ' Help</div><div class="p" style="background:transparent url(/images/themes/skin1/window_controls.png) repeat scroll -13px -33px;height:14px;width:14px;position:absolute;right:0px;top:0px;" onclick="client.windows.'+this.id+'.__help();"></div>';
			var tempHelpCanvas = createObject("div", "dhWin_" + this.id + "_helpCanvas", 	"helpCanvas contentCanvas", 	tmpWindow,'<div class="helpCanvasTitle">'+html+'</div>'+'<div class="helpCanvasCanvas">' + this.helpText+ '</div>');


			var tmpTitleBar = 	createObject("div", "dhWin_" + this.id + "_titleBar", 			"a titleBar " + ((this.draggable) ? "m" : ""),		 		tmpWindow);
			var icon = 			createObject("div", "dhWin_" + this.id + "_icon", 				"windowIcon windowIdent", 		tmpTitleBar);
			var title = 		createObject("div",	"dhWin_" + this.id + "_title", 				"windowTitle windowIdent", 		tmpTitleBar);

			var tmpTabBar = 	createObject("div", "dhWin_" + this.id + "_tabBar", 			"a tabBar", 		tmpWindow);
								createObject("div", "dhWin_" + this.id + "_tabBar_bg_left", 	"tabBar_bg_left", 	tmpTabBar);
								createObject("div", "dhWin_" + this.id + "_tabBar_bg_right", 	"tabBar_bg_right", 	tmpTabBar);

			var tmpTabBarCanvas = createObject("div", "dhWin_" + this.id + "_tabBarCanvas", 	"tabBarCanvas", 	tmpTabBar);



			var tmpStatusBar = 	createObject("div", "dhWin_" + this.id + "_statusBar", 			"a statusBar", 		tmpWindow);
			var tmpStatusText =	createObject("div", "dhWin_" + this.id + "_statusBarCaption", 	"statusBarText", 	tmpStatusBar);

			//--------------
			// create optional elements
			//--------------
			this.menuBox = 			createObject("div",	"dhWin_" + this.id + "_menuBox", 				"a tr highZ menuBox", 		tmpWindow);
			if(this.closeButton)
				this.closeBox = 		createObject("div",	"dhWin_" + this.id + "_controlBox", 		"controlBox windowControls", 	tmpTitleBar);
			if(this.maximizeButton)
				this.maximizeBox = 		createObject("div",	"dhWin_" + this.id + "_maximizeBox", 		"maximizeBox windowControls", 	tmpTitleBar);
			if(this.reloadButton)
				this.reloadBox = 		createObject("div", "dhWin_" + this.id + "_reloadBox", 			"reloadBox windowControls", 	tmpTitleBar);
			if(this.helpButton)
				this.helpBox = 			createObject("div", "dhWin_" + this.id + "_helpBox", 			"helpBox windowControls", 		tmpTitleBar);

			//generate some resize handles
			//no need to store a reference, these will not be used as often as some other elements
			//we'll use getobject when necessary, they have names
			if(this.resizable){
				createObject("div", "dhWin_" + this.id + '_resizeTL' , 	'a highZ tl 	resizeTL', 	tmpWindow, dhNull);
				createObject("div", "dhWin_" + this.id + '_resizeT' , 	'a highZ top 	resizeT', 	tmpWindow, dhNull);
				createObject("div", "dhWin_" + this.id + '_resizeTR' , 	'a highZ tr		resizeTR', 	tmpWindow, dhNull);
				createObject("div", "dhWin_" + this.id + '_resizeR' , 	'a highZ right	resizeR', 	tmpWindow, dhNull);
				createObject("div", "dhWin_" + this.id + '_resizeBR' , 	'a highZ br 	resizeBR', 	tmpWindow, dhNull);
				createObject("div", "dhWin_" + this.id + '_resizeB' , 	'a highZ bottom resizeB', 	tmpWindow, dhNull);
				createObject("div", "dhWin_" + this.id + '_resizeBL' , 	'a highZ bl 	resizeBL', 	tmpWindow, dhNull);
				createObject("div", "dhWin_" + this.id + '_resizeL' , 	'a highZ left 	resizeL', 	tmpWindow, dhNull);
				this.resizeHandle = createObject("div", "dhWin_" + this.id + "_resizeHandle", 		"a resizeHandle",	tmpStatusBar);
			}

			
		},

		//--------------
		//find and add optional elements
		//--------------
		addOptionalElements : function (){
			if(this.closeButton)	this.closeBox = 		getObject("dhWin_" + this.id + "_controlBox");
			if(this.maximizeButton)	this.maximizeBox = 		getObject("dhWin_" + this.id + "_maximizeBox");
			if(this.menuButton)		this.menuBox = 			getObject("dhWin_" + this.id + "_menuBox");
			if(this.reloadButton) 	this.reloadBox = 		getObject("dhWin_" + this.id + "_reloadBox");
			if(this.resizable)		this.resizeHandle = 	getObject("dhWin_" + this.id + "_resizeHandle");
		},

		//---------------
		// DHTML Adds
		//---------------
		addObjects : function (){
			

			this.windowNode = 	dh.addObject("dhWin_" + this.id , 					this.fadeIn + this.fadeOut + captureToParent + ( (this.alwaysOnTop) ? alwaysOnTop : '' ));
			this.dropShadow = 	dh.addObject("dhWin_" + this.id + "_dropShadow" , 	none);
			this.bg1 = 			dh.addObject("dhWin_" + this.id + "_bg1",			none);
			this.bg2 =			dh.addObject("dhWin_" + this.id + "_bg2", 			none);
			this.titleBar = 	dh.addObject("dhWin_" + this.id + "_titleBar", 		none);
			this.icon = 		dh.addObject("dhWin_" + this.id + "_icon",			none);
			this.titleNode =	dh.addObject("dhWin_" + this.id + "_title",			none);

			this.tabBar = 		dh.addObject("dhWin_" + this.id + "_tabBar", 		(this.tabsVisible) ? "" : hidden );
			this.tabBarCanvas = dh.addObject("dhWin_" + this.id + "_tabBarCanvas", none);
			this.loader = 		dh.addObject("dhWin_" + this.id + "_loader", 		hidden);
			this.canvas = 		dh.addObject("dhWin_" + this.id + "_canvas", 		none);
			this.statusBar = 	dh.addObject("dhWin_" + this.id + "_statusBar", 	(this.statusVisible) ? "" : hidden );

			this.statusBarCaption = dh.addObject("dhWin_" + this.id + "_statusBarCaption", none);

			if(getObject("dhWin_" + this.id + "_helpCanvas")){
				this.helpCanvas = 	dh.addObject("dhWin_" + this.id + "_helpCanvas",hidden);
			}

		},

		initObjects : function(){
			var myID = this.id;

			//--------------
			//Ident Graphics
			//--------------
			if( this.iconVisible ) {
				//this.icon.setBgImage( ecirkitImagesURL + "themes/testing/" + this.popupPrefix + this.id + "_icon.png");
			}
			if( this.titleVisible ) {
				 this.titleNode.write( this.windowTitle );
			}

			//--------------
			//Control Boxes
			//--------------
			if( this.closeButton ){
				JSTip(this.closeBox, "Click here to close this window.");
				this.closeBox.onclick = function(){ client.windows[myID].__close(); };
				this.closeBox.onmousedown = function(e) { dh.getEventObject(e); dh.stopEvent(); return false; };
			}
			if( this.maximizeButton ){
				JSTip(this.maximizeBox, "Click here to maximize this window.");
				this.maximizeBox.onclick = function(){ client.windows[myID].__maximize(); };
				this.maximizeBox.onmousedown = function(e) { dh.getEventObject(e); dh.stopEvent(); return false; };
			}
			if(this.reloadButton) {
				JSTip(this.reloadBox, "Click here to reload this window's content.");
				this.reloadBox.onclick = function(){ client.windows[myID].__reload(); };
				this.reloadBox.onmousedown = function(e) { dh.getEventObject(e); dh.stopEvent(); return false; };
			}
			if(this.menuBox){
				JSTip(this.menuBox, "Click here to see more options.");
				this.menuBox.onclick = function(){ client.windows[myID].__menu(); };
				this.menuBox.onmousedown = function(e) { dh.getEventObject(e); dh.stopEvent(); return false; };
			}

			if(this.helpBox){
				JSTip(this.helpBox, "Click here for help.");
				this.helpBox.onclick = function(){ client.windows[myID].__help(); };
				this.helpBox.onmousedown = function(e) { dh.getEventObject(e); dh.stopEvent(); return false; };
				this.helpBox.ondblclick = function(e) { dh.getEventObject(e); dh.stopEvent(); return false; };
			}

			//----------
			//Tab Bar
			//----------
			// 	not completely written
			// 	this section would be used to generate tabs and all necessary objects at the time of window creation
			//  with an additional parameter, alternativly to using the tab related methods after window creation is
			//	complete.
			//
			//if(tabCollection) this.setTabs(tabCollection);

			//----------
			//Status Bar
			//----------
			if( this.resizable ) {
				getObject("dhWin_" + this.id + '_resizeTL'	).onmousedown = function(){ client.windows[ myID ].__beginResize( 'tl' 	) };
				getObject("dhWin_" + this.id + '_resizeT'	).onmousedown = function(){ client.windows[ myID ].__beginResize( 't' 	) };
				getObject("dhWin_" + this.id + '_resizeTR'	).onmousedown = function(){ client.windows[ myID ].__beginResize( 'tr' 	) };
				getObject("dhWin_" + this.id + '_resizeR'	).onmousedown = function(){ client.windows[ myID ].__beginResize( 'r' 	) };
				getObject("dhWin_" + this.id + '_resizeBR'	).onmousedown = function(){ client.windows[ myID ].__beginResize( 'br' 	) };
				getObject("dhWin_" + this.id + '_resizeB'	).onmousedown = function(){ client.windows[ myID ].__beginResize( 'b' 	) };
				getObject("dhWin_" + this.id + '_resizeBL'	).onmousedown = function(){ client.windows[ myID ].__beginResize( 'bl' 	) };
				getObject("dhWin_" + this.id + '_resizeL'	).onmousedown = function(){ client.windows[ myID ].__beginResize( 'l' 	) };
				//this.resizeHandle.onmousedown = function () { client.__beginResize( dh.nodes["dhWin_" + myID] ); };
			}
			//----------
			//Help Canvas Bar
			//----------
			if(this.helpCanvas){
				var instance = this;
				this.helpCanvas.onShow = function(){if(instance.y < 130)instance.windowNode.moveTo(dhNull,130);}
			}

			//some event handling mapping
			this.windowNode.onMouseDown = function () {
				if( isAncestorOf( dh.eventTargetElement, client.windows[ myID ].windowNode.obj ))
				client.windows[ myID ].windowNode.bringToFront();
				if(client.windows[ myID ].onBringToFront){
					client.windows[ myID ].onBringToFront();
				}
				return true;
			};
			this.windowNode.onDrop = function () { return client.windows[myID].__drop(); };
			this.windowNode.onGrab = function () { return client.windows[myID].__grab(); };
			this.windowNode.onResize = function () { return client.windows[myID].__resize(); };
			this.titleBar.onDblClick = function () { return client.windows[myID].__shade(); };

			//some defaults
			this.loader.setOpacity(70);

			//set the window style
			this.setWindowStyle( this.windowStyle );
		},

		setWindowStyle: function ( style ){
			var tabBar;
			var titleBar;
			var statusBar;
			switch( style ){
				case windowStyle.canvas:
					titleBar = 	false;
					tabBar = 	false;
					statusBar = false;
					break;
				case windowStyle.popup:
					titleBar = 	true;
					tabBar = 	this.tabsVisible;
					statusBar = this.statusVisible;
					break;
				case windowStyle.pane:
					titleBar = 	true;
					tabBar = 	this.tabsVisible;
					statusBar = this.statusVisible;
					this.bg1.setOpacity(client.paneOpacity);
					break;
				default:
					break;
			}

			if(tabBar){		this.tabBar.show(); } 	else { this.tabBar.hide(); }
			if(titleBar){ 	this.titleBar.show(); }	else { this.titleBar.hide(); }
			if(statusBar){ 	this.statusBar.show();} else { this.statusBar.hide(); }
		},


		/* Perspectives
		 * A managed way to load all window state info
		 *
		 * use as follows
		 * 1 Argumnent
		 *function( {Object}stateInfo )
		 *
		*   stateInfo example
		 * 	{
		 * 		state
		 * 		x
		 * 		y
		 * 		w
		 * 		h
		 * 		visible
		 * 	}
		 *
		 * -or-
		 * multiple arguments
		 * function(state, x, y, w, h, visible)
		 *
		 */
		loadStateObject : function ( ){

			this.useWindowProcessor = false;

			if( arguments.length == 0 ) return false;

			//passed in object
			if( arguments.length == 1 ) {
				//make sure we got an object
				if( !isObject( arguments[0] ) ) return false;


			//multiple parameters
			} else {

				//state?
				if( arguments[0] ){
					this.setWindowState( arguments[0] );
				}
				//x?
				if( arguments[1] ){
					this.windowNode( arguments[0] );
				}

				//y?
				if( arguments[2] ){
				}

				//w?
				if( arguments[3] ){
				}

				//h?
				if( arguments[4] ){
				}

				//visible?
				if( arguments[5] ){
				}

			}

			this.useWindowProcessor = true;

			return true;
		},

		//Set the state of the window
		setWindowState : function ( state ){
			var tmpLast = this.windowState;
			this.windowState = state;
			try{
				//set some normally used defaults
				//set default titlebar cursor
				if( this.draggable ) this.titleBar.setCursor( cursors.move );
				//dh.nodes.canvas.setStyle('overflow', 'auto');

				//make us movebale again if we're suppoed to be
				if( state != windowState.maximized )
				if( this.draggable )
				this.windowNode.draggable = true;

				//set state specifics
				switch ( state ){
					case windowState.minimized:
						//minimization
						this.hide();
						//turn this off so when the window is sized during restore, the client won't automatically
						//save the settings agsin. the save handlers are attached to events that check this flag
						this.useWindowProcessor = false;
						break;
					case windowState.normal:
						//in the event of being shaded
						if(this.tabsVisible) this.tabBar.showNow();
						if(this.statusVisible) this.statusBar.showNow();
						this.bg1.showNow();
						this.bg2.showNow();
						this.canvas.showNow();

						//show again if we were hidden ( minimized )
						if( this.visible != true ) this.show();

						//call the resize handler
						//this is called by show i think
						//yup. i just checked.
						//this.__resize();

						//disable the save handler for maximized windows
						this.useWindowProcessor = true;

						break;
					case windowState.shaded:
						//disable the save handler for shaded windows
						//this should avctualyl be enabled but there is no windowstate field in the db
						this.useWindowProcessor = false;

						//show again if we were hidden ( minimized )
						if( this.visible != true ) this.show();

						break;
					case windowState.maximized:
						//disable the save handler for maximized windows
						this.useWindowProcessor = false;

						//show again if we were hidden ( minimized )
						if( this.visible != true ){
							this.show();
						}

						//in the event of being shaded
						if(this.tabsVisible) this.tabBar.showNow();
						if(this.statusVisible) this.statusBar.showNow();
						this.canvas.showNow();
						this.bg1.showNow();
						this.bg2.showNow();

						//can't drag when maximized
						this.windowNode.draggable = false;
						this.titleBar.setCursor( cursors.normal );

						//dh.nodes.canvas.setStyle('overflow', 'hidden');
						this.scrollTop = document.body.parentNode.scrollTop;
						//resize the content and exit
						this.__resize();
						break;
				}
			} catch ( ex ) {
				
				return false;
			}
			this.lastWindowState = tmpLast;
			return true;
		},

		setCanvas: function ( dhNode ){
			dhNode.setParent( this.canvas.id );
			dhNode.showNow();
			this.currentCanvas = dhNode;
		},

		setLoading: function ( loading ){
			if(loading == true){
				this.loader.show();
				this.loader.bringToFront();
			} else {
				this.loader.hide();
			}
		},

		setStatus: function (statusText){
			this.statusBarCaption.write(statusText);
		},

		setTitle : function ( newTitle ){
			var titleObject = getObject('dhWin_' + this.id + '_title');
			titleObject.innerHTML = newTitle;
		},

		getTitle : function ( ){
			var titleObject = getObject('dhWin_' + this.id + '_title');
			return titleObject.innerHTML;
		},
		/*-------------------------------------------
		 * Adds a tab to the Tabs collection
		 *
		 * 		tabKey:  		string
		 * 		caption: 		string
		 * 		HTMLElement: 	object or id of object
		 * 		DHObject:
		 * 		action:	 		function for onSelect
		 -------------------------------------------*/
		addTab: function( id, caption, DHCanvas, closeable ){
			try{
				var firstTab = false;
				if( this.tabCount == 0 ) firstTab = true;

				var newTab = new DHTab( id, caption, this.tabBarCanvas, DHCanvas, closeable );
				this.tabs[this.tabs.length] = newTab;

				newTab.parentWindow = this;

				if(DHCanvas){
					if( !isObject(DHCanvas) ){
						if( getObject(DHCanvas) ) {
							 //DHCanvas = dh.addObject(DHCanvas, none);
						} else {
							//create a canvas here
						}

					}
					DHCanvas.setParent( this.canvas.obj );
				}

				if( firstTab ){
					this.__tab(id);
				} else {
					newTab.canvas.hideNow();
				}

				this.tabCount++;
			} catch (e){
				
				return false;
			}
			client.addHelpBeacon("community",newTab.tabElement.obj,'windowTab');
			/*client.addHelpBeacon("community",DHCanvas.obj,'windowCanvas');*/
			return newTab;
		},

		getTabIndex : function( tabKey ){
			for( var j = 0; j < this.tabs.length; j++ ){
				if( this.tabs[j].id == tabKey ) return j;
			}
		},

		getTab : function( tabKey ){
			if( isNumber( tabKey ) )
			try{
				return this.tabs[ this.getTabID( tabID ) ];
			} catch (ex){ }
			return false;
		},

		getSelectedTab : function(){
			return this.selectedTab;
		},

		getSelectedTabKey : function(){
			return selectedTab.id;
		},

		//this can take an index or a key
		removeTab : function ( id ){
			var index = -1;

			if( isString(id) ){
				index = this.getTabIndex( id );
			} else {
				index = id;
			}

			this.tabs[index].close();
			this.tabs.splice( index , 1 );
			this.tabCount--;
			//do we still have any tabs?
			if( this.tabs.length > 0 ){
				//yup, select anoter tab
				if( index >= this.tabs.length ) {
					index = this.tabs.length - 1;
				}
				this.__tab(index);
			}
		},

		reflowWindowElements : function (){
			//if(this.resizable){
				//since we can also see the resize peices then size the ones that need sizing
			W( getObject("dhWin_" + this.id + '_resizeT'), this.windowNode.getW() - 20);
			H( getObject("dhWin_" + this.id + '_resizeR'), this.windowNode.getH() - 20);
			W( getObject("dhWin_" + this.id + '_resizeB'), this.windowNode.getW() - 20);
			H( getObject("dhWin_" + this.id + '_resizeL'), this.windowNode.getH() - 20);

			W( getObject("dhWin_" + this.id + '_borderT'), this.windowNode.getW() - 20);
			H( getObject("dhWin_" + this.id + '_borderR'), this.windowNode.getH() - 20);
			W( getObject("dhWin_" + this.id + '_borderB'), this.windowNode.getW() - 20);
			H( getObject("dhWin_" + this.id + '_borderL'), this.windowNode.getH() - 20);


			//this is actually theme specific, but i don't need to make a whole chucnk of code to get it. we only hav1 skin now anyways
			var borderWidth = 3;
			var innerWindowSize = [ this.windowNode.w - (borderWidth * 2), this.windowNode.h - (borderWidth * 2) ];

			//the following will only apply to elements that are visible in ALL window states
			if(this.titleBar){
				//this.titleBar.moveTo(0,0);
				this.titleBar.W( this.windowNode.w  - getW( getObject("dhWin_" + this.id + "_menuBox") ) );
			}

			if(this.helpCanvas){
				H(this.helpCanvas.obj.lastChild,130- 27);
			}

			this.dropShadow.moveTo(			borderWidth, 			borderWidth);
			this.dropShadow.resizeTo( 		this.windowNode.w, 		this.windowNode.h );

			//the following from here only applyto windows with content that is visible
			// suchas when the window isn't minimized or shaded
			if(this.windowState != windowState.minimized &&
				this.windowState != windowState.shaded){

				//this math will only be needed in here
				var currentYoffset = 0;

				//if the titlebar is visible then move our Y offset pointer down to match
				if(this.titleBar.visible) currentYoffset += this.titleBar.getH() + this.titleBar.y;

				//position the loading screen so that it hovers over tabs
				this.loader.moveTo( 		borderWidth, 			currentYoffset );
				this.loader.resizeTo( 		innerWindowSize[0] , 	(innerWindowSize[1] - currentYoffset ) );

				if( this.tabBar ){
					this.tabBar.moveTo(	borderWidth, currentYoffset);
					this.tabBar.W( innerWindowSize[0] );
				}

				if(this.tabBar.visible) currentYoffset += this.tabBar.getH();

				if(this.statusBar){
					this.statusBar.Y( this.windowNode.h - this.statusBar.getH() - borderWidth );
					this.statusBar.W( this.windowNode.w - borderWidth - this.statusBar.x );
				}

				var canvasWidth = innerWindowSize[0] - (client.windowXPadding * 2);
				var canvasHeight =  (innerWindowSize[1] - currentYoffset) - (client.windowXPadding * 2);

				if( this.statusBar.visible ) canvasHeight -= (this.statusBar.h);

				//these go full size i think so size em now
				this.bg1.moveTo( borderWidth, borderWidth);
				this.bg2.moveTo( borderWidth, borderWidth);

				this.bg1.resizeTo( innerWindowSize[0], 	innerWindowSize[1]);
				this.bg2.resizeTo( innerWindowSize[0], 	innerWindowSize[1]);

				this.canvas.moveTo( 		borderWidth + client.windowXPadding , 	currentYoffset + client.windowYPadding );
				this.canvas.resizeTo( 		canvasWidth, 							canvasHeight );

				if( this.tabCount > 0 ){
					//if a tab is selected, tell its canvas to call any resize handler
					this.selectedTab.canvas.invoke("Resize");
				}

			}

		},

		fitCurrentCanvas: function (){
			this.currentCanvas.moveTo(0,0);
			this.currentCanvas.resizeTo( this.canvas.W() , this.canvas.H() );
		},

		show: function (){
			//do we center on show?
			if( this.centerOnShow || this.windowNode.centerOnShow){
				this.windowNode.centerViewport();
				this.windowNode.moveTo( this.windowNode.x , this.windowNode.y - dh.nodes.header.h);
				this.x = this.windowNode.x;
				this.y = this.windowNode.y;
				this.normalPosition = [this.x , this.y];
			}

			//do we need a position and now have one?
			if(this.x == null && this.windowPositioning == windowPositioning.absolute){
				client.setCascadePosition( this );
			}

			//are we minimized
			if(this.windowState == windowState.minimized){
				//yup, animate a popup
				// and exit, everthing is taken care of from here, it'll make it's way back
				this.restore();
				return;
			}
			if(this.windowState == windowState.maximized){
				//yup, animate a popup
				// and exit, everthing is taken care of from here, it'll make it's way back
				document.body.parentNode.scrollTop = 0;
			}

			this.windowNode.show();
			this.windowNode.bringToFront();
			this.visible = true;

			this.useWindowProcessor = false;
			this.__resize();
			this.useWindowProcessor = true;

			if( this.initialized == false ){
				this.invoke("Load");
				this.initialized = true;
			}

			this.invoke("Show");

			//save
			this.saveUserSettings('setWindowOpen');

			//after the first display ( or after being restored once ) it will always be true, then it saves it's settings
			//we might not want this behavior.
			this.useWindowProcessor = true;
			client.currentWindow = this;

		},

		hide: function (){

			this.windowNode.hide();
			this.visible = false;
			this.invoke("Hide");

			this.saveUserSettings('setWindowClose');
		},

		showNow: function (){

			 if(this.x == null && this.windowPositioning == windowPositioning.absolute){
				client.setCascadePosition( this );
				this.normalSize = [this.windowNode.w , this.windowNode.h ];
			}

			if(this.windowState == windowState.minimized){
				this.restore();
				return;
			}

			this.windowNode.showNow();
			this.windowNode.bringToFront();
			this.visible = true;
			this.invoke("Show");
		},

		hideNow: function (){
			this.windowNode.hideNow();
			this.visible = false;
			this.invoke("Hide");
		},

		maximize: function(){
			//all vaules are relative to viewport
			//scroll Values added in later
			var destX = 0;
			var destY = 0;
			var destW = dh.viewportW ;
			var destH = dh.viewportH - dh.nodes.header.h;

			//tell the window
			this.setWindowState( windowState.maximized );

			//maximization
			this.windowNode.resizeTo( destW , destH );
			this.windowNode.moveTo(destX, 0);

			document.body.parentNode.scrollTop = 0;

			/*
			var myID = this.id;
			dh.nodes.resizeAnimation.resizeTo(this.windowNode.w, this.windowNode.h);
			dh.nodes.resizeAnimation.moveTo(this.windowNode.getAbsX() - 2, this.windowNode.getAbsY() - 2);

			dh.nodes.resizeAnimation.bringToFront();
			dh.nodes.resizeAnimation.show();

			dh.nodes.resizeAnimation.animate(
				new dh.tweenDetails(
					destX + dh.scrollLeft,
					destY + dh.nodes.header.h,
					destW,
					destH,
					100,
					parseFloat(".5"),
					5
				),
				function (){
					//clean up
					dh.nodes.resizeAnimation.hide();

					//tell the window
					client.windows[myID].setWindowState( windowState.maximized );

					//maximization
					client.windows[myID].windowNode.resizeTo( destW , destH );
					client.windows[myID].windowNode.moveTo(destX, 0);
				}
			);
			*/
			this.invoke("Maximize");
		},

		minimize: function (){

			this.setWindowState( windowState.minimized );

			/*
			var myID = this.id;

			var destX = 0;
			var destY = 0;
			var destW = 0;
			var destH = 0;

			if( this.minimizeTo ) {
				destX = this.minimizeTo.getAbsX();
				destY = this.minimizeTo.getAbsY();
				destW = this.minimizeTo.w;
				destH = this.minimizeTo.h;
			}

			dh.nodes.resizeAnimation.resizeTo(this.windowNode.w, this.windowNode.h);
			dh.nodes.resizeAnimation.moveTo(this.windowNode.getAbsX() - 2, this.windowNode.getAbsY() - 2);

			dh.nodes.resizeAnimation.bringToFront();
			dh.nodes.resizeAnimation.show();

			dh.nodes.resizeAnimation.animate(
				new dh.tweenDetails(
					destX + dh.scrollLeft,
					destY + dh.scrollTop,
					destW,
					destH,
					100,
					parseFloat(".5"),
					5
				),
				function (){
					//clean up
					dh.nodes.resizeAnimation.hide();

					//tell the window to go away, he's being annoying and keeps stealing my toys
					client.windows[myID].setWindowState( windowState.minimized );
				}
			);
			*/

			this.invoke("Minimize");
		},

		restore: function() {
			var myID = this.id;
			var newState = windowState.normal;
			var destX = 0;
			var destY = 0;
			var destW = 0;
			var destH = 0;

			if(this.windowState == windowState.normal){ return; }
			//alert(this.lastWindowState);
			if(this.lastWindowState == windowState.maximized ){
				/*destX = 20;
				destY = 0;
				destW = dh.viewportW - 40;
				destH = dh.viewportH - 20 - dh.nodes.header.h;
				newState = windowState.maximized;*/
				this.maximize();
				this.invoke("Restore");
				return;
			} else if( this.lastWindowState == windowState.shaded ){
				//was it shaded?
				client.windows[myID].tabBar.hideNow();
				client.windows[myID].statusBar.hideNow();
				client.windows[myID].canvas.hideNow();

				destX = client.windows[myID].normalPosition[0]; //scrolltop accounted for
				destY = client.windows[myID].normalPosition[1];
				destW = client.windows[myID].normalSize[0];
				destH = client.windows[myID].titleBar.h;
				newState = windowState.shaded;
			} else {
				//either it was normal or
				//it was minimized so use normal
				destX = client.windows[myID].normalPosition[0]; //scrolltop accounted for
				destY = client.windows[myID].normalPosition[1];
				destW = client.windows[myID].normalSize[0];
				destH = client.windows[myID].normalSize[1];
				document.body.parentNode.scrollTop = this.scrollTop;
			}

			/*
			if(this.windowState == windowState.minimized ){
				//minimized
				dh.nodes.resizeAnimation.resizeTo(0, 0);
				dh.nodes.resizeAnimation.moveTo(dh.mouseX, dh.mouseY);
			}
			else{
				//closed
				dh.nodes.resizeAnimation.resizeTo( this.windowNode.w , this.windowNode.h);
				dh.nodes.resizeAnimation.moveTo(this.windowNode.getAbsX() , this.windowNode.getAbsY() );
			}

			dh.nodes.resizeAnimation.bringToFront();
			dh.nodes.resizeAnimation.show();

			dh.nodes.resizeAnimation.animate(
				new dh.tweenDetails(
					destX,
					destY + dh.nodes.header.h,
					destW,
					destH,
					100,
					parseFloat(".5"),
					5
				),
				function (){
					//clean up
					dh.nodes.resizeAnimation.hide();

					//resize
					client.windows[myID].windowNode.moveTo(destX + dh.scrollLeft, destY + dh.scrollTop);
					client.windows[myID].windowNode.resizeTo(destW , destH);

					//tell the window
					client.windows[myID].setWindowState(newState);
				}
			);
			*/

			//resize
			this.windowNode.moveTo(destX + dh.scrollLeft, destY + dh.scrollTop);
			this.windowNode.resizeTo(destW , destH);

			//tell the window
			this.setWindowState(newState);

			this.invoke("Restore");
		},

		rollUp: function(){
			var myID = this.id;
			/*
			this.setWindowState( windowState.shaded );
			this.windowNode.animate(
				new dh.tweenDetails( dhNull, dhNull, dhNull, this.titleBar.h , dhNull, parseFloat(".5") , 5 ),
				function () {
					client.windows[myID].tabBar.hideNow();
					client.windows[myID].statusBar.hideNow();
					client.windows[myID].canvas.hideNow();
				}
			);
			*/
			this.setWindowState( windowState.shaded );
			this.windowNode.resizeTo(dhNull, this.titleBar.h );
			client.windows[myID].tabBar.hideNow();
			client.windows[myID].statusBar.hideNow();
			client.windows[myID].canvas.hideNow();
			client.windows[myID].bg1.hideNow();
			client.windows[myID].bg2.hideNow();
		},

		rollDown: function(){
			var myID = this.id;
			/*
			client.windows[myID].setWindowState( windowState.normal );

			this.windowNode.animate(
				new dh.tweenDetails( dhNull, dhNull, dhNull, this.normalSize[1], dhNull, parseFloat(".5") , 5 ),
				function () {  }
			);
			*/
			client.windows[myID].setWindowState( windowState.normal );
			this.windowNode.resizeTo(dhNull, this.normalSize[1]);
		},

	//-----------------------------
	// Incomming Event Handlers
	//-----------------------------
		__beginResize : function ( side ) {
			var myID = this.id;

			if(this.windowState == windowState.maximized)return false;
			//don't resize non-resizable elements
			if( !this.resizable){
				//dbugArea.innerHTML += (element.id+" is <strong>NOT</strong> resizable <br / >");
				return false;
			}


			client.showGlobalMatte('matteClear');

			var sizeFunc = null;
			switch(side){
				case 'tl':
					sizeFunc = (this.windowState == windowState.shaded ) ? windowResizeFunctions.left : windowResizeFunctions.topLeft;
					break;
				case 't':
					sizeFunc = (this.windowState == windowState.shaded ) ? function (){} : windowResizeFunctions.top;
					break;
				case 'tr':
					sizeFunc = (this.windowState == windowState.shaded ) ? windowResizeFunctions.right : windowResizeFunctions.topRight;
					break;
				case 'r':
					sizeFunc = windowResizeFunctions.right;
					break;
				case 'br':
					sizeFunc = (this.windowState == windowState.shaded ) ? windowResizeFunctions.right : windowResizeFunctions.bottomRight;
					break;
				case 'b':
					sizeFunc = (this.windowState == windowState.shaded ) ? function (){} : windowResizeFunctions.bottom;
					break;
				case 'bl':
					sizeFunc = (this.windowState == windowState.shaded ) ? windowResizeFunctions.left : windowResizeFunctions.bottomLeft;
					break;
				case 'l':
					sizeFunc = windowResizeFunctions.left;
					break;
				default:
					break;
			}

			this.windowNode.bringToFront();
			client.resizingWindow = this;
			client.resizeBorderWidth = parseInt(dh.nodes.resizeAnimation.getStyle('border-top-width'));
			if(dh.safari){ client.resizeBorderWidth = 2; }

			dh.nodes.resizeAnimation.resizeTo(this.windowNode.w, this.windowNode.h);

			dh.nodes.resizeAnimation.moveTo(this.windowNode.getAbsX() - client.resizeBorderWidth, this.windowNode.getAbsY() - client.resizeBorderWidth);

			client.resizeMinSize = [ this.minW, this.minH ];
			client.resizeStartPos = [ dh.nodes.resizeAnimation.x , dh.nodes.resizeAnimation.y ];
			client.resizeStartSize = [ dh.nodes.resizeAnimation.w , dh.nodes.resizeAnimation.h ];

			dh.nodes.resizeAnimation.bringToFront();
			dh.nodes.resizeAnimation.show();

			dh.addMouseMoveEvent('resizing', sizeFunc );
			dh.addMouseUpEvent('stop_resizing', function(){ client.windows[myID].__endResize() } );
		},

		__endResize : function (){
			dh.removeMouseMoveEvent('resizing');
			dh.removeMouseUpEvent('stop_resizing');

			this.windowNode.resizeTo(dh.nodes.resizeAnimation.w, dh.nodes.resizeAnimation.h);
			this.windowNode.moveTo( this.x - (client.resizeStartPos[0] - dh.nodes.resizeAnimation.x),
						 			this.y - (client.resizeStartPos[1] - dh.nodes.resizeAnimation.y));

			dh.nodes.resizeAnimation.hide();

			client.closeMatte();
		},

		//finished resizing
		__resize : function (){
			if( this.windowState == windowState.normal ){
				this.normalSize = [ this.windowNode.w , this.windowNode.h ];
				this.normalPosition = [ this.windowNode.X() , this.windowNode.Y() ];
				this.x = this.windowNode.x;
				this.y = this.windowNode.y;

				this.saveUserSettings();
			}
			//since the window has some visible content, resize the peices
			this.reflowWindowElements();

			this.invoke("Resize");
		},

		//minimize clicked
		__minimize:function (){
			if( this.windowState == windowState.minimized){
				return this.restore();
			} else {
				return this.minimize();
			}
		},

		//maxmimize button clicked
		__maximize:function(){
			if( this.windowState == windowState.maximized ){
				return this.restore();
			} else {
				return this.maximize();
			}
		},

		//shade button clicked
		__shade: function (){
			if( this.windowState == windowState.maximized ){
				return false;
			}
			if( this.windowState == windowState.shaded ){
				return this.rollDown();
			} else {
				return this.rollUp();
			}
		},

		__menu : function (){

			var myID = this.id;
			var menuObj = {};

			if(this.helpButton )
			menuObj.help = {
				caption : "Show Help",
				callback : "client.windows['"+myID+"'].__help();"
			}

			if(this.reloadButton )
			menuObj.reload = {
				caption : "Reload Data",
				callback : "client.windows['"+myID+"'].__reload();"
			}

			if(this.maximizeButton )
			menuObj.maximize = {
				caption : "Maximize Window",
				callback : "client.windows['"+myID+"'].__maximize()"
			}

			if(this.closeButton )
			menuObj.close = {
				caption : "Close Window",
				callback : "client.windows['"+myID+"'].__close();"
			}

			var fromElement = getObject("dhWin_" + this.id + "_menuBox");
			client.showPopupMenu( menuObj,
									getAbsX(fromElement) + getW(fromElement),
									getAbsY(fromElement)
								);

		},

		//reload button clicked
		__reload: function (){
			this.invoke("Reload");
		},

		//help button clicked
		__help: function (){
			if(!this.helpCanvas)return;

			if(this.helpCanvas.visible){
				this.helpCanvas.hide();
			}else{
				this.helpCanvas.show();
			}

			this.saveUserSettings();

			this.invoke("Help");
		},

		//sudo close the window
		__close:function(){
			if ( this.invoke("Close") ){
				this.hide();
			} else {
				//
			}
		},

		__grab: function(){
			//this.windowNode.animate( new dh.tweenDetails( dhNull, dhNull, dhNull, dhNull, 60, .2 , 4), function () {} );
			if(this.windowState == windowState.maximized ) return false;

			if( this.windowState == windowState.normal ) {
				this.bg1.setOpacity(client.dragOpacity);
				this.canvas.hideNow();
			}
			return true;
		},

		__drop: function(){

			if( this.windowState == windowState.normal ) {
				//this.windowNode.animate( new dh.tweenDetails( dhNull, dhNull, dhNull, dhNull, 100, .2 , 4), function () {} );
				this.bg1.setOpacity(client.windowOpacity);
				this.canvas.showNow();
			}

			this.x = this.windowNode.X();
			this.y = this.windowNode.Y();

			if( this.windowState == windowState.normal || this.windowState == windowState.shaded ){
				this.normalPosition = [this.x , this.y];
			}

			this.saveUserSettings();

			//this.normalPosition = [ this.x , this.windowNode.getAbsY() ];
			return true;
		},

		//incomming event for a tab click
		//this much also call which ever tab's onSelect
		__tab: function( tabKey ){

			if(tabKey == dhNull ){
				if(!this.selectedTab) return;
				tabKey = this.selectedTabIndex;
			}

			var tabIndex = tabKey;
			if( isString( tabIndex ) ) tabIndex = this.getTabIndex( tabKey );

			//deselect any other selected tabs
			if(this.selectedTab != null){
				this.selectedTab.__deselect();
			}

			this.selectedTabIndex = tabIndex;
			this.selectedTab = this.tabs[tabIndex];
			this.currentCanvas = this.selectedTab.canvas;
			this.selectedTab.__select();

			this.useWindowProcessor = false;
			if( this.visible ) this.__resize();
			this.useWindowProcessor = true;

			this.invoke('Tab', this.selectedTab.id );
		},

		__windowToggle : function(){
			if( this.visible && client.currentWindow == this){
				this.minimize();
			}else { this.show();}
		}
};

//**********************************************************************
//
//  DHTML Based Tab
//
//**********************************************************************
function DHTab( id, caption, tabBarCanvas, DHObject, closeable) {
	this.id = id;
	this.caption = caption;
	this.canvas = DHObject;
	this.tabCanvas = tabBarCanvas;

	if( this.tabCanvas ) {
		this.tabElement = dh.createDHObject("div", id, "tab tabWrap tab_deselected", this.tabCanvas.obj , dhNull, none);

		createObject("div", dhNull, "tab tabLeftBorder", this.tabElement.obj);

		this.textElement = createObject("div", id + "_text", "tab tabText", this.tabElement.obj , this.caption);

		if( closeable ){
			var closeButtonBG = createObject("div", dhNull, "tab_close_bg", this.tabElement.obj );
			this.closeButton = createObject("div", dhNull, "tab_close", closeButtonBG );
		}

		createObject("div", dhNull, "tab tabRightBorder", this.tabElement.obj);

		var myself = this;
		if( closeable ) this.closeButton.onclick = function (){ myself.parentWindow.removeTab( myself.id ); dh.stopEvent(); return false; };
		this.tabElement.onClick = function(){ myself.__click(); };
	}
}
DHTab.prototype = {
	//--------------------------
	// Properties
	//--------------------------
	id:				'',
	caption:		null,
	tabCanvas:		null,
	parentWindow:	null,
	selected: 		false,
	tabElement:		null,
	canvas:			null,
	selected:		false,

	//--------------------------
	// Tab Events
	//--------------------------
	onSelect: 	null,
	onDeselect:	null,

	//--------------------------
	// Methods
	//--------------------------
	setCaption : function (caption){
		this.caption = caption;
		this.textElement.innerHTML = caption;
	},

	invoke: function( ev ){
		try{ return this['on'+ev](); } catch (ex) {  } return true
	},

	close : function ( ){

		if( !this.invoke("Close") ) return;

		this.canvas.destroy();
		this.tabElement.destroy();
	},
	//--------------------------
	// Incomming Events
	//--------------------------

	//click is handled by addTab in the window
	__click: function (){
		if( !this.selected ){
			this.parentWindow.__tab(this.id);
		}
	},

	__close: function(){
		return this.close();
	},

	//incomming select event
	__select: function () {
		//var selection = window.getSelection();
		//if(selection.containsNode( this.tabElement, true ) ){
		//	var body = document.getElementsByTagName("body")[0];
		//	window.getSelection().collapse(body,0);
		//}
		this.tabElement.obj.className = this.tabElement.obj.className.replace("tab_deselected", "tab_selected");
		this.selected = true;
		this.canvas.show();
		this.invoke('Show');
	},
	__deselect: function () {
		this.tabElement.obj.className = this.tabElement.obj.className.replace("tab_selected", "tab_deselected");
		this.selected = false;
		this.canvas.hide();
		this.invoke('Hide');
	}
}

function initCarousel(){
	if(!client.windows.carousel){
		client.addWindow( 'carousel',
			{
				startingPosition: 	[/*x*/ 0, /*y*/ 0],
				windowStyle:		windowStyle.pane,
				windowPositioning:	windowPositioning.floatLeft,
				windowSizing:		windowSizing.fillHoriz,
				startingState:		windowState.normal,
				resizable:			false,
				reloadButton:		true,
				closeButton:		false,
				shadeButton:		true,
				maximizeButton: 	false,
				minimizeButton: 	false,
				showTabs:			true,
				showStatus:			true,
				showTitle:			true,
				showIcon:			false,
				draggable: 			false
			},
			dh.nodes.profile_row1.obj,
			"Media"
		);
		client.windows.carousel.addTab( 'videos' ,  'VIDEOS',	dh.nodes.videosCanvas );
		client.windows.carousel.addTab( 'photos' , 	'PHOTOS' , 	dh.nodes.photosCanvas );
		
		//client.windows.carousel.addTab( 'music' ,   'MUSIC',	dh.nodes.musicCanvas );
		dh.nodes.videosCanvas.onShow = function () { fetchProfileVideos(); };
		dh.nodes.photosCanvas.onShow = function () { 
			dh.nodes.photosCanvas.obj.tree.loadFiles(null,function(){
				//if(!dh.nodes.photosCanvas.obj.tree.countFiles())
					//client.windows.carousel.__tab('videos');
					//getObject('photosCanvas_list').innerHTML = 'This user has no photos.';
			}); 
			clearProfileVideoContent();
			
		};
		//dh.nodes.musicCanvas.onShow = function (){  };
		//createFlash( dh.nodes.musicCanvas.obj , '/flash/audio_player.swf', 'profile_music', 640, 415, false);

		client.windows.carousel.onShow = function(){client.windows.carousel.currentCanvas.show();};
		client.windows.carousel.onReload = function () { this.show(); };

		client.windows.carousel.photoTree = new FileTree(
				dh.nodes.photosCanvas.obj ,
				-1 ,
				{
					header:false,
					menu:false,
					msg:false,
					breadcrumb:true,
					sideBar:false,
					display:"gallery",
					window:client.windows.carousel,
					initData:client.data.profilePictures
				} ,
				"photos"
			);
		//initProfilePhotoViewer();
		//client.windowFunctions.photoViewer.init();
	}
}
/****************************************************
 *
 *
 * 		User Photos
 *
 *
 ****************************************************/

function showPhotoRemarkWindow( data ){
	if(!client.nameSpaces.photoViewer){
		client.initNameSpace("photoViewer","window",function(){showPhotoRemarkWindow( data );});
		return false;
	}
	client.nameSpaces.photoViewer.setCurrPhoto(data);
	client.windows.photoViewer.show();
}


/*
 * ePromptIt - prompt window class
 * 
 * Hopefully this will make pop up windows, for dialogs and alerts a little easier.
 * 
 */
var promptButtons = {
	ok : {
		ok : "OK"
	},
	yesNo : {
		yes : 	'Yes',
		no : 	'No'
	},
	okCancel : {
		ok : 		'OK',
		cancel : 	'Cancel'
	},
	abortRetryIgnore : {
		abort :		'Abort',
		retry : 	'Retry',
		ignore :	'Ignore'
	},
	timeoutButtons : {
		login :		'Log back in',
		splash : 	'Go to the splash page',
		nothing :	'Do Nothing'
	}	
};

/*
 * For each theme there is a matteTheme, which is a css class
 * a icon theme which is also a css class
 * and a form bg classname
 */
var promptThemes = {
	notice : {
			matte : 'matteUserNotice',
			icon :	'dialogIconNotice',
			bg	:	''
		},
	error : {
			matte : 'matteUserError',
			icon :	'dialogIconError',
			bg	:	''
		},
	warning : {
			matte : 'matteUserWarning',
			icon :	'dialogIconWarning',
			bg	:	''
		},
	question : {
			matte : 'matteUserPrompt',
			icon :	'dialogIconQuestion',
			bg	:	''
		}
	};

/**
 * Display a user alert or dialog
 * @param {string} 	title		A window title for the dialog
 * @param {string} 	caption  	A message to be displayed
 * @param {function}callback 	A function to recieve the user selection
 * @param {Object} 	buttons		An element from the dialogButtons collection
 * @param {Object} 	theme		A theme fro mthe promptThemes collection
 * @param {Integer} timeout		An amount of time in miliseconds before auto-close.
 */
function ePromptIt( title, caption, callback, buttons, theme, timeout ){
	//some default values
	if( !buttons ) buttons = promptButtons.ok;
	if( !theme ) theme = promptThemes.notice;

	//show our themed matte
	client.showWorkspaceMatte( theme.matte );

	//if no dialog window has been made yet, then generate one really quickly
	if( !client.windows.userDialog ){
		this.buildWindow();
	}

	//clear our old buttons, from the last time we used our slutty window
	dh.nodes.userDialogButtonCanvas.purge();

	//generate our new buttons
	for(var a in buttons){
		var b = dh.createDHObject( 'div', 'userDialogButton' + buttons[a], "dialogButton mr10 " + a + "Button", dh.nodes.userDialogButtonCanvas.obj, buttons[a], none);
		if( callback ) client.windows.userDialog.callback = callback;
		b.onClick = Function("client.windows.userDialog.response = '"+ buttons[a] +"'; client.windows.userDialog.__close();");
	}
	
	client.windows.userDialog.setTitle( title );
	dh.nodes.userDialogCaption.write( caption );
	client.windows.userDialog.show();
	
	if( timeout ){
		this.closeTimer = setTimeout(
			function (){ 
				client.windows.userDialog.response = 'timeout'
				client.windows.userDialog.__close();
		 	},
			timeout
		);
	}
}

ePromptIt.prototype = {
	buildWindow : function (){
		client.addWindow( 'userDialog',
		 	{
		 		securityLevel	:	windowSecurity.unsecured,
		 		title :				"",
		 		windowStyle :		windowStyle.popup,
		 		windowSizing :		windowSizing.manual,
		 		windowPositioning : windowPositioning.absolute,
		 		startingState :		windowState.normal,
		 		centerOnShow :		true,
				alwaysOnTop : 		true,
		 		fadeOut :			true,
		 		draggable :			false,
		 		resizable :			false,
		 		showIcon :			false,
				showTitle :			true,
		 		showTabs :			false,
				showStatus :		false,
		 		minimizeButton :	false,
		 		maximizeButton :	false,
		 		rollupButton :		false,
		 		closeButton :		true,
		 		shadeButton:		false
		 	},
			dh.nodes.windowspace.obj
		);

		dh.addObject("userDialogCanvas", 		none);
		dh.addObject("userDialogCaption" , 		none);
		dh.addObject("userDialogButtons" , 		none);
		dh.addObject("userDialogButtonCanvas" , none);

		client.windows.userDialog.setCanvas( dh.nodes.userDialogCanvas );
		
		//move the caption and size it according to windoiwPAdding values
		dh.nodes.userDialogCaption.moveTo(client.windowXPadding, client.windowYPadding);
				
		client.windows.userDialog.onClose = function (){
	
			//empty the timeout to close the form if there was one
			if( client.windows.userDialog.closeTimer ) clearTimeout(client.windows.userDialog.closeTimer);

			client.windows.userDialog.hide();
			client.closeMatte();
			
			if( client.windows.userDialog.callback ){
				client.windows.userDialog.callback( client.windows.userDialog.response );
				delete client.windows.userDialog.callback;
			}
		}
		
		client.windows.userDialog.onShow = function (){
			//re-read the height of the caption text
			dh.nodes.userDialogCaption.obj.style.height = 'auto';
			dh.nodes.userDialogCaption.initialize();
			dh.nodes.userDialogCaption.resizeTo(client.windows.userDialog.windowNode - (client.windowXPadding * 2) , 
				dh.nodes.userDialogCaption.h);
			
			//move the buttons down past the text, and add some windowYPadding
			dh.nodes.userDialogButtons.Y(dh.nodes.userDialogCaption.h + ( client.windowXPadding * 2) );
			
			//re-read the button canvas width and write it explicity for the margin auto to work.
			dh.nodes.userDialogButtonCanvas.obj.style.position = 'absolute';
			dh.nodes.userDialogButtonCanvas.obj.style.width = 'auto';
			dh.nodes.userDialogButtonCanvas.initialize();
			dh.nodes.userDialogButtonCanvas.obj.style.position = "relative";
			dh.nodes.userDialogButtonCanvas.W(dh.nodes.userDialogButtonCanvas.w);
			
			//get the new window sizes
			var wH = client.windowXPadding +
						dh.nodes.userDialogCaption.h + 
						((client.windows.userDialog.titleBar.visible) ? client.windows.userDialog.titleBar.h : 0) +
						((client.windows.userDialog.statusBar.visible) ? client.windows.userDialog.statusBar.h : 0) +
						(client.windowYPadding * 4) +
						dh.nodes.userDialogButtonCanvas.h;
			
			//resize the window			
			client.windows.userDialog.windowNode.resizeTo( client.windows.userDialog.windowNode.w, wH );
		}
	}
};
function eFormit(){
	this.elements ={};
	
	this.types = {};
	
	this.types['text'] = [];
	this.types['area'] = [];
	this.types['checkbox'] = [];
	this.types['radio'] = [];
	this.types['button'] = [];
	this.types['select'] = [];
	this.types['hidden'] = [];
	this.types['password'] = [];
	this.types['cusSel'] = [];
}

eFormit.prototype = {
	elements:null,
	types:null,
	
	init : function(){
		
	},
	
	empty : function(){
		this.destroy();
		this.elements ={};
	
		this.types = {};
		
		this.types['text'] = [];
		this.types['area'] = [];
		this.types['checkbox'] = [];
		this.types['radio'] = [];
		this.types['button'] = [];
		this.types['select'] = [];
		this.types['hidden'] = [];
		this.types['password'] = [];
		this.types['cusSel'] = [];
	},
	
	destroy : function(){
		delete this.elements;
		delete this.types;
	},
	
	parseForm : function(formObj){
		var inputs = formObj.getElementsByTagName("input");
		var textArea = formObj.getElementsByTagName("textarea");
		var select = formObj.getElementsByTagName("select");
		
		for(i  = 0 ; i < inputs.length; i++){
			this.elements[inputs[i].id] = {"obj":inputs[i],"type":inputs[i].type};
			this.types[inputs[i].type].push(inputs[i]);
		}

		for(i  = 0 ; i < textArea.length; i++){
			this.elements[textArea[i].id] = {"obj":textArea[i],"type":"area"};
			this.types["area"].push(textArea[i]);
		}

		for(i  = 0 ; i < select.length; i++){
			this.elements[select[i].id] = {"obj":select[i],"type":"select"};
			this.types["select"].push(select[i]);
		}
	},
	
	addElement : function (obj, type, defaultState , beacon){
		this.elements[obj.id] = {"obj":obj,"type":type};
		
		switch(type){
			case "checkbox":
			case "radio":
				obj.checked = defaultState;
				break;
			default :
				if(defaultState){
					obj.value = defaultState;
				}else{
					obj.value = '';
				}
				break;			
		}
		this.types[type].push(obj);
		if(beacon){
			/*client.addHelpBeacon("community",obj,obj.id);
			client.addHelpBeacon("webtop",obj,obj.id);*/
		}
	},
	
	getValue : function(id){
		if(this.elements[id].type == "radio"){
			return this.getRadioValue(this.elements[id].obj.name);
		}
		if(this.elements[id].type == "checkbox"){
			return this.elements[id].obj.checked;
		}
		if(this.elements[id].type == "cusSel"){
			return getCusSelVal( this.elements[id].obj );
		}
		return this.elements[id].obj.value;
	},
	
	setValue : function (id, value){
		var element = this.elements[id];
		var obj = element.obj;
		var type = element.type;
		
		switch(type){
			case "checkbox":
			case "radio":
				obj.checked = value;
				break;
			case "cusSel":
				setCusSelVal( obj , value);
				break;
			default :
				if(value){
					obj.value = value;
				}else{
					obj.value = '';
				}
				break;			
		}
	},
		
	getRadioValue : function( group ){
		for(key in this.types['radio']){
			if((this.types['radio'][key].name == group) && !this.types['radio'][key].disabled && (this.types['radio'][key].checked))
				return this.types['radio'][key].value;
		}
		
		return -1;
	},
	
	setRadioGroupState : function( group , state){
		for(key in this.types['radio']){
			if(this.types['radio'][key].name == group){
				this.types['radio'][key].disabled = !state;
			}
		}
	},
	
	setState : function( id , state){
		var obj = this.elements[id].obj;
		var className = '';
		if(obj.className){
			className = obj.className;
		}
		className = className.replace(/(\sformFail)|(formFail)/g,'');
		className = className.replace(/(\sformPass)|(formPass)/g,'');
		if(state){
			className += " formPass";
		}else{
			className += " formFail";
		}
		obj.className = className;
	},

	getJSON : function(){
		var data = {};
		for(key in this.elements){
			switch(this.elements[key].type){
				case 'hidden':
				case 'password':
				case 'text':
				case 'area':
				case 'select':
				case 'cusSel':
					data[key] = this.getValue(key);
					break;
				case 'radio':
					data[this.elements[key].obj.name] = this.getValue(key);
					break;
				case 'checkbox':
					if(this.getValue(key))
						data[key] = 1;
					else
						data[key] = 0;
					break;
				default:
					break;
			}
		}
		return data;
	}
}
/**
 * @author john
 */
function initSearchIt(){
	client.windowFunctions.searchIt = function(){
		return {
			
			win : null,
			wrapper : null,
			
			searchArea : null,
			resultArea : null,
			
			resultTabBar : null,
			resultDeck : null,
			
			currCard : null,
			currTab : null,
			cardDeck : [],
			
			form : null,
			
			winName : null,
			nameName : null,
			searchResults : null,
			
			init : function(){
				this.nameSpaceSettings();
	
				if(!client.windows[this.winName]){
					this.buildWindowObj();
				}
				this.buildWindow();
			},
			
			addCard : function( searchObj ){
				var card = this.buildResultCard( searchObj );
				this.resultDeck.appendChild(card);
				this.addTab(card , searchObj);
			},
			
			addTab : function( card ,searchObj){
				var thisSpace = this;
				var tab = this.buildResultTab(searchObj);
					tab.obj = {tab:tab,card:card};
					tab.onclick = function(){thisSpace.setCurCard(this.obj);}
				this.resultTabBar.appendChild(tab);
				this.cardDeck.push(tab.obj);
				this.setCurCard( tab.obj );
			},
			
			buildResultCard : function( searchObj ){

				var html = 	'<div style="position:relative;width:100%;height:20px;">Search Info</div>'+
							'<div style="position:relative;width:100%;height:0px;overflow:auto;"></div>';				
				var card = createObject("div",dhNull,"contentCanvas a o f",dhNull,html);
				card.lastChild.innerHTML = this.buildCardContent(searchObj);
				return card;
			},
			
			buildCardContent : function (searchObj){
				if(searchObj.ResultSet){
					var html = '';
					for(key in searchObj.ResultSet.Result){
						var data = searchObj.ResultSet.Result[key];
						html += this.yahooResultHTML(data);
					}
					return html;
				}else{
					var query = ((searchObj.search=="Google") ? 'http://www.google.com/search?hl=en&q='+htmlspecialchars_bitcode(searchObj.searchItField)+'&btnG=Google+Search' : 'http://www.mahalo.com/Special:Search?search='+htmlspecialchars_bitcode(searchObj.searchItField));
					return '<iframe class="a o f"  src="'+query+'"><iframe>';
				}
			},
			
			yahooResultHTML : function ( result ){
				var html= 	'<div class="yahooSearchResult">'+
								'<div '+
									'onclick="loadInBrowser({Url:\''+result.ClickUrl+'\',title:\''+result.Url+'\',description:\''+htmlspecialchars_bitcode(result.Title.substr(0,20))+'\'})" '+
								'class="yahooSearchResultTitle p">'+result.Title+'</div>'+
								'<div class="yahooSearchResultSummary">'+result.Summary+'</div>'+
								'<div class="yahooSearchResultURL">'+
									'<div class="fl">Url&nbsp;:&nbsp;</div>'+
									'<div '+
									'onclick="loadInBrowser({Url:\''+result.ClickUrl+'\',title:\''+result.Url+'\',description:\''+htmlspecialchars_bitcode(result.Title.substr(0,20))+'\'})" '+
									'class="fl p" style="text-decoration : underline;color : #0000ff;">'+result.DisplayUrl+'</div>'+
								'</div>'+
							'</div>';
				return html;
			},
			
			buildResultTab : function(searchObj){
				var html = 	'<div class="fl">'+searchObj.search+'</div>'+
							'<div '+
							'onclick="'+this.nameName+'.removeCard(this.parentNode.obj);"'+
							'class="fl tab_close" style="margin-left:5px;">'+
								'<img class="tab_close_img" src="/images/spacer.gif">'+
							'</div>';
				var tab = createObject("div",dhNull,"tab_deselected",dhNull,html);
					tab.paddingRight = "0px";
				return tab;
			},
			
			buildWindowObj : function(){
				var thisSpace = this;
				if(!client.windows[this.winName]){
					client.addWindow( this.winName,
						{
							startingState:		windowState.normal,
							windowStyle:		windowStyle.popup,
							windowPositioning:	windowPositioning.absolute,
							windowSizing:		windowSizing.manual,
							closeButton:		false,
							draggable:			true,
							fadeInOut:			false,
							maximizeButton:		true,
							minimizeButton:		false,
							resizable:			true,
							shadeButton:		true,
							showIcon:			true,
							showTitle:			true,
							showTabs:			false,
							showStatus:			true
						},
						dh.nodes.windowspace.obj,
						"Search"
					);
					this.win = client.windows[this.winName];
					this.win.onResize = function(){thisSpace.onResize();};
					
				}
			},
			
			buildWindow : function (){
				if(!this.wrapper){
					this.wrapper = dh.createDHObject("div","searchItCanvas","contentCanvas a o f",canvasStorage);
					this.win.setCanvas(this.wrapper);
				}
				this.wrapper.obj.innerHTML = this.canvasHTML();
				this.searchArea = this.wrapper.obj.childNodes[0];
				this.resultArea = this.wrapper.obj.childNodes[1];
				
				this.searchArea.innerHTML = this.searchHTML();
				this.resultArea.innerHTML = this.resultHTML();
				
				this.resultTabBar = this.resultArea.childNodes[0];
				this.resultDeck = this.resultArea.childNodes[1];
				

				this.initForm();
				
				this.win.windowNode.resizeTo(600,500);
			},
			
			canvasHTML : function (){
				var html = 	'<div id="searchItSearch" '+
							'style="position: relative; height:90px; width:100%;"></div>'+
							'<div id="searchItResult" '+
							'style="position: relative; height:0px; width:100%;"></div>';
				return html;
			},
			
			searchHTML : function(){
				var html =  '<div style="clear:left;" class="a o f">'+
								'<div class="fl" style="margin:5px;overflow:auto;">'+
									'<input '+
									'onkeypress="if(!event)var event=window.event; if((event.keyCode || event.which) == 13)'+this.nameName+'.sendSearch(this.parentNode.nextSibling.firstChild.firstChild)"'+
									'type="text" id="searchItField" name="searchItField" />'+
								'</div>'+
								'<div class="fl" style="margin:5px;">'+
									'<div style="clear:left;">'+
										'<input '+
										'onclick="'+this.nameName+'.sendSearch(this);"'+
										'type="button" class="" value="Mahalo" />'+
									'</div>'+
									'<div style="clear:left;">'+
										'<input '+
										'onclick="'+this.nameName+'.sendSearch(this);"'+
										'type="button" class="" value="Google" />'+
									'</div>'+
									'<div style="clear:left;">'+
										'<input '+
										'onclick="'+this.nameName+'.sendSearch(this);"'+
										'type="button" class="" value="Yahoo" />'+
									'</div>'+
								'</div>'+
							'</div>';
				
				return html;
			},
			
			resultHTML : function (){
				var html = 	'<div style="position:relative;width:100%;height:20px;clear:left;"></div>'+
							'<div style="position:relative;width:100%;height:0px"></div>';
							
				return html;
			},
			
			fetchWindowData : function(){

			},
			
			fetchSearchData : function ( searchType ){

			},
			
			initForm : function(){
				if(this.form){
					this.form.destroy();
					delete this.form;
				}
				var form = new eFormit();
				form.addElement(getObject('searchItField'),'text',getObject('searchItField').value);
				//form.addElement(getObject('searchItMahalo'),'radio',true);
				//form.addElement(getObject('searchItGoogle'),'radio', false);

				this.form = form;
			},
			
			nameSpaceSettings : function (){
				this.winName = "searchIt";
				this.nameName = "client.windowFunctions.searchIt";
			},
			
			onResize : function (){
				if(this.resultArea){
					fillVertically(this.resultArea);
				}
				if(this.resultDeck){
					fillVertically(this.resultDeck);
				}
				if(this.currCard){
					fillVertically(this.currCard.lastChild);
				}
			},

			removeCard : function(obj){
				var tab = obj.tab;
				var card = obj.card;
				var index = indexOf(this.cardDeck, obj);
				
				tab.parentNode.removeChild(tab);
				card.parentNode.removeChild(card);
				this.cardDeck.splice(index,1);
				
				if(this.cardDeck.length)
					this.setCurCard(this.cardDeck[0]);
			},

			sendSearch : function (button){
				if(!this.form)return;
				var thisSpace = this;
				var data = this.form.getJSON();
					data.search= button.value;
				
				if(data.search == "Yahoo"){
					var yahooPost = {	appid:'ZXpPscTV34Fn31YAm3Gm.99Q5xH25FnoGGehP3IeVsF.C3IwxIIC3WPfxedzIkTf5Qo',
										query:data.searchItField,
										start:1,
										output:'json'
									};
					ajax.post(
						"/api/processors/yahooSearch",
						yahooPost,
						function(conn){
							if(conn.responseObject){
								//console.log(conn.responseObject);
								conn.responseObject.search = data.search;
								thisSpace.addCard(conn.responseObject);
							}
						},
						function(conn){
	
						},this.win
					);
				}else{
					thisSpace.addCard(data);
				}
				
				
			},
			
			setCurCard : function ( obj ){
				var tab = obj.tab;
				var card = obj.card;
				
				if(this.currTab){
					this.currTab.className = this.currTab.className.replace(/(tab_selected)|(\stab_selected)/g,'');
				}
				this.currTab = tab;
				this.currTab.className += " tab_selected";
				
				if(this.currCard){
					hideObject(this.currCard);
				}
				this.currCard = card;
				showObject(this.currCard);
				fillVertically(this.currCard.lastChild);
			}
		}
	}();
}
//---------------------------
//Windshield
//---------------------------

function initProfileWindshield (){

	if ( !client.windows.windshield ){

		dh.addObject('interestsCanvas', 	none); //Windshield
			dh.addObject('interestsList', 	none);

		dh.addObject('remarksCanvas', 		none);
			dh.addObject('userRemarks', 	none);
			dh.addObject('remarksVCRTop', 	none);
			dh.addObject('remarksVCRBottom',none);

		dh.addObject('userBookmarksCanvas', none);
		dh.addObject('vaultCanvas', 		none);
		dh.addObject('rssCanvas', 			none); //RSS

		client.addWindow( 'windshield',
			{
				startingPosition: 	[/*x*/ 0, /*y*/ 0],
				windowStyle:		windowStyle.pane,
				windowPositioning:	windowPositioning.floatLeft,
				windowSizing:		windowSizing.fillHoriz,
				startingState:		windowState.normal,
				resizable:			false,
				closeButton:		false,
				shadeButton:		true,
				maximizeButton: 	false,
				minimizeButton: 	false,
				reloadButton : 		true,
				showTabs:			true,
				showStatus:			true,
				showIcon:			false,
				draggable: 			false
			},
			dh.nodes.profile_column2.obj,
			"Portfolio"
		).windowNode.onMouseDown = null;
		client.windows.windshield.addTab( "remarks", 	"Remarks", 	dh.nodes.remarksCanvas );
		client.windows.windshield.addTab( "bio", 		"Bio", 		dh.nodes.interestsCanvas );
		client.windows.windshield.addTab( "blogs", 		"Blogs", 	dh.createDHObject('div', 'blogsCanvas' , 		'a o f', canvasStorage) );
		client.windows.windshield.addTab( "rss", 		"RSS",		dh.createDHObject('div', 'profileRssCanvas' , 	'a o f', canvasStorage) );
		client.windows.windshield.addTab( "bookmarks", 	"Bookmarks",dh.nodes.userBookmarksCanvas );
		client.windows.windshield.addTab( "vaultCanvasTab", "Vault",dh.nodes.vaultCanvas );
		client.windows.windshield.addTab( "forsale", 	"For Sale", dh.createDHObject('div', 'forSaleCanvas' , 		'a o f', canvasStorage) );

		dh.nodes.remarks.obj.helpKey = dh.nodes.remarksCanvas.id;
		dh.nodes.bio.obj.helpKey = dh.nodes.interestsCanvas.id;
		dh.nodes.blogs.obj.helpKey = dh.nodes.blogsCanvas.id;
		dh.nodes.rss.obj.helpKey = dh.nodes.profileRssCanvas.id;
		dh.nodes.bookmarks.obj.helpKey = dh.nodes.userBookmarksCanvas.id;
		dh.nodes.vaultCanvasTab.obj.helpKey = dh.nodes.vaultCanvas.id;
		dh.nodes.forsale.obj.helpKey = dh.nodes.forSaleCanvas.id;


		client.windows.windshield.onTab = windshield_tab;
		client.windows.windshield.onResize = windshieldResize;
		client.windows.windshield.onLoad = function () { client.windows.windshield.__tab('bio'); };
		client.windows.windshield.onReload = function windwShieldReload()
		{
					//windshield
			delete client.data.profileBlogs;
			delete client.data.profileBookmarks;
			delete client.data.profileVault;
			delete client.data.profileForSale;
			delete client.data.contestRemarks;
			delete client.data.profileRemarks;
			// Rss
			delete client.data.profileRssFeeds;
			//Media
			delete client.data.profileVideos;
			delete client.data.profileMusic;
			delete client.data.profilePhotos;
			//contacts
			delete client.data.profileContacts;
			client.windows.windshield.__tab(); /*force a reload of the current tab*/
		};

		dh.nodes.remarksCanvas.onResize = resizeRemarksCanvas;
	}
}

function initLeaveRemark(){
	if(!client.windows.leaveRemark){
		//---------------------------
		//News Pane
		//---------------------------
		client.addWindow( 'leaveRemark',
			{
				startingState:	windowState.minimized,
				windowStyle:		windowStyle.pane,
				centerOnShow:	true,
				resizable:		false,
				closeButton:	true,
				maximizeButton: false,
				minimizeButton: false,
				shadeButton:	false,
				showTabs:		false,
				showStatus:		false,
				showIcon:		false,
				alwaysOnTop : true
			},
			dh.nodes.windowspace.obj,
			"Leave Remark"
		);
		client.windows.leaveRemark.setCanvas( dh.nodes.leaveRemarkCanvas );
		client.windows.leaveRemark.onClose = function () {
			client.closeMatte();
			client.windows.leaveRemark.minimize();
			return false;
		};
	}

}

function stopRemarksFlash() {

	//var profileRemarks = getObject("remarksCanvas");
	//profileRemarks.innerHTML = profileRemarks.innerHTML;
	//console.log("stoprEmarksFlash - 122 windshield.js");
	//showRemarks();

}

/****************************************************************
 *
 * 			Windshield Show, Resize, an Tab
 *
 *
 ***************************************************************/
function windshield_tab( tabKey ){

	if(tabKey  != 'bio'){
		try{
			dh.nodes.showEditInterestsButton.destroy();
			delete dh.nodes.showEditInterestsButton;
		}catch(ex){}
	}

	if(tabKey  != 'remarks'){
		stopRemarksFlash();
	}

	switch( tabKey ) {
		case "bio":
			showInterests();
			break;
		case "remarks":
			showRemarks();
			break;
		case "blogs":
			fetchProfileBlogs();
			break;
		case "rss":
			initProfileRss();
			break;
		case "bookmarks":
			fetchUserBookmarks();
			break;
		case "vaultCanvasTab":
			fetchUserVault();
			break;
		case "forsale":
			fetchProfileForSale();
			break;

	}
	return true;
}


function windshieldResize(){
	//client.windows.windshield.currentCanvas.invoke("Show");
	return true;
}

function windshield_init(){
	client.windows.windshield.currentCanvas.show();
}

/*******************************************************
 *
 * 			Interests -  Show, Build, Edit
 *
 *
 ******************************************************/
function fetchUserDetails( data ){
	if(!client.isHomeProfile() || !data){
		var data = {type:'userDetails'};
	}else{
		var value;
		for(key in data){
		if(key != "type" && key != "value")
			if(key == "detail"){
				key = data[key];
				value = data['value'];
			}else{
				value = data[key];
			}
			client.getBrowseUserObject().user_details[key] = value;
			showInterests();
		}
	}

	ajax.post(	"/api/processors/user",
					data,
				 	function( conn ){
						//client.getBrowseUserObject().user_details = conn.responseObject;
						//showInterests();
					},
					function( conn ){
						//client.getBrowseUserObject().user_details = conn.responseObject;
						//showInterests();
					}
				);
}

function fetchUserInterests( data ){
	if(!client.isHomeProfile() || !data){
		var data = {type:'userInterests'};
	}else{
		for(key in data){
		if(key != "type")
			client.getBrowseUserObject().user_interests[data['itype']] = data['data'];
			showInterests();
			if(client.windowFunctions.mySettings && client.windowFunctions.mySettings.selOpt == 1){
				client.windowFunctions.mySettings.cancel.onclick();
			}
		}
	}

	ajax.post(	"/api/processors/user",
					data,
				 	function( conn ){
						//client.getBrowseUserObject().user_interests = conn.responseObject;
						//showInterests();
					},
					function( conn ){
						//client.getBrowseUserObject().user_interests = conn.responseObject;
						//showInterests();
					}
				);
}
function editInterestInline( obj , interest){
	var value = obj.innerHTML;
	var html = 	'<textarea '+
				'style="width:95%"'+
				'>'+
					value+
				'</textarea>';
	obj.innerHTML = html;
	obj.parentNode.ondblclick = null;

	obj.firstChild.onblur = function(e){
		sendInterestEdit( this.value , interest,obj);
	}

	obj.firstChild.onkeydown = function(e){
		if(!e)var e = window.event;
		if((e.keyCode || e.which) == 13) {
			sendInterestEdit( this.value , interest,obj);
			return false;
		}
	}
	obj.firstChild.focus();
}

function editDetailsInline(obj , detail){
	obj.ondblclick = null;
	//obj = obj.lastChild;
	var value = obj.lastChild.innerHTML;
	var html = 	'<input '+
				'type="text" '+
				'style="width:95%" '+
				'value="'+value+'" '+
				'onfocus="this.select();"'+
				' />';;

	obj.innerHTML = html;
	obj.ondblclick = null;

	obj.firstChild.onblur = function(e){
		sendDetailsEdit( this.value , detail,obj);
	}

	obj.firstChild.onkeydown = function(e){
		if(!e)var e = window.event;
		if((e.keyCode || e.which) == 13) {
			sendDetailsEdit( this.value , detail,obj);
			return false;
		}
	}
	obj.firstChild.focus();
}

function editHeightWeightInline(obj){
	obj.ondblclick = null;
	var str = obj.lastChild.innerHTML;
	var currFt = str.replace(/(.*)'(.*)"\/(.*) lbs./,'$1');
	var currIn = str.replace(/(.*)'(.*)"\/(.*) lbs./,'$2');
	var currWeight = str.replace(/(.*)'(.*)"\/(.*) lbs./,'$3');

	var html = '<div class="fl"><table><tbody><tr><td><select id="detailFeet" style="width:100%;">'+
					'<option value="N/A"></option>';
	for(var x = 3; x < 10;x++){
		html += '<option value="'+x+'" '+
			((x == currFt)?'selected':'')+
			'>'+
			x+
			((x == 3)? ' -':((x == 9)? ' +': '') )+
		'</option>';
	}
	html += '</select></td></tr></tbody></table></div><div class="fl">&nbsp;ft&nbsp;</div>';

	html += '<div class="fl"><table><tbody><tr><td><select id="detailInch" style="width:100%;">'+
					'<option value="N/A"></option>';
	for(var x = 0; x < 12;x++){
		html += '<option value="'+x+'" '+
			((x == currIn)?'selected':'')+
			'>'+
			x+
		'</option>';
	}
	html += '</select></td></tr></tbody></table></div><div class="fl">&nbsp;in&nbsp;</div>';

	html += '<div class="fl"><table><tbody><tr><td><select id="detailWeight" style="width:100%;">'+
					'<option value="N/A"></option>';
	for(var x = 90; x < 300;x += 5){
		html += '<option value="'+x+'" '+
			((x == currWeight)?'selected':'')+
			'>'+
			x+
			((x == 300)? ' +': ((x == 90)? ' -': ''))+
		'</option>';
	}
	html += '</select></td></tr></tbody></table></div><div class="fl">&nbsp;lbs&nbsp;</div>';
	obj.innerHTML = html;
	var selects = obj.getElementsByTagName("select");
	for(id in selects){
		var sel = selects[id];
		sel.onkeydown = function(e){
			if(!e)var e = window.event;
			if((e.keyCode || e.which) == 13) {
				sendHeightWeightEdit( this.value);
				return false;
			}
		}
		sel.onblur = function(){
			client.getBrowseUserObject().timeoutHW =  setTimeout(
				function(){
					sendHeightWeightEdit( this.value );
				},
				100
			);
		}
		sel.onfocus = function(){
			clearTimeout(client.getBrowseUserObject().timeoutHW);
		}
	}
	selects[0].focus();
}
function editZodiacInline (obj ){
	obj.ondblclick = null;
	var signs = {
		Aries : "The Ram",
		Taurus : "The Bull",
		Gemini : "The Twins",
		Cancer : "The Crab",
		Leo : "The Lion",
		Virgo : "The Virgin",
		Libra : "The Scales",
		Scorpius : "The Scorpion",
		Sagittarius : "The Archer",
		Capricornus : "The Sea-goat",
		Aquarius : "The Water-bearer",
		Pisces : "The Fishes"
	}

	//alert(dumpObj(signs));
	var currSign = obj.lastChild.innerHTML;
	var html = '';
	html += '<div class="fl"><table><tbody><tr><td><select '+
					'style="width:95%;"'+
					'onchange="sendDetailsEdit( this.value , \'zodiac\',obj);"'+
					'onblur="sendDetailsEdit( this.value , \'zodiac\',obj);"'+
					'>';
	
	for(sign in signs){
		html +=	'<option value="'+sign+'" '+
							((sign == currSign)?'selected':'')+
							'>'+
								sign+' ('+signs[sign]+')'+
							'</option>';
	}
	html += '</select></td></tr></tbody></table></div>';
	//alert(html);
	obj.innerHTML = html;
	obj.firstChild.focus();
}
/*function editSmokeDrinkInline(obj , detail){
	obj.ondblclick = null;
	var str = obj.lastChild.innerHTML;
	var currSmoke = (str.replace(/(.*)\/(.*)/,'$1') == 'Yes') ? 'checked' : '';
	var currDrink = (str.replace(/(.*)\/(.*)/,'$2') == 'Yes') ? 'checked' : '';

	var html = 'Smoke :'+
				'<input id="detailSmoke" type="checkbox" '+currSmoke+'/>'+
				'Drink :'+
				'<input id="detailDrink" type="checkbox" '+currDrink+'/>';
	obj.innerHTML = html;

	var checkBoxs = obj.getElementsByTagName("input");
	for(id in checkBoxs){
		var checkBox = checkBoxs[id];
		checkBox.onkeydown = function(e){
			if(!e)var e = window.event;
			if((e.keyCode || e.which) == 13) {
				sendSmokeDrinkEdit( this.value , detail,checkBox);
				return false;
			}
		}
		checkBox.onblur = function(){
			client.getBrowseUserObject().timeoutCheck =  setTimeout(
				function(){
					sendSmokeDrinkEdit( this.value , detail,checkBox);
				},
				100
			);
		}
		checkBox.onfocus = function(){
			clearTimeout(client.getBrowseUserObject().timeoutCheck);
		}
	}
	checkBoxs[0].focus();
}*/
function editAgeSexInline(obj ){
	obj.ondblclick = null;
	var str = obj.lastChild.innerHTML;
	var currSex = str.replace(/(.*)\/(.*)/,'$1');
	var currAge = str.replace(/(.*)\/(.*)/,'$2');

	currSex = (currSex == 'M')? 1 : 0;
	var html = '<div class="fl">Sex&nbsp;:&nbsp;</div><div class="fl"><table><tbody><tr><td><select id="detailSex">'+
					'<option value="M" '+((currSex)? ' selected':'')+'>Male</option>'+
					'<option value="F"'+((currSex)? '':' selected')+'>Female</option>'+
				'</select></td></tr></tbody></table></div>';

	html += '<div class="fl">&nbsp;Age&nbsp;:&nbsp;</div><div class="fl"><table><tbody><tr><td><select id="detailYear">'+
					'<option value="N/A"></option>';
	for(var x = 18; x < 100;x++){
		html += '<option value="'+x+'" '+
			((x == currAge)?'selected':'')+
			'>'+
			x+
			((x == 99)? ' +': '')+
		'</option>';
	}
	html += '</select></td></tr></tbody></table></div>';

	obj.innerHTML = html;

	var selects = obj.getElementsByTagName("select");
	for(id in selects){
		var sel = selects[id];
		sel.onkeydown = function(e){
			if(!e)var e = window.event;
			if((e.keyCode || e.which) == 13) {
				sendSexAgeEdit( this.value);
				return false;
			}
		}
		sel.onblur = function(){
			client.getBrowseUserObject().timeoutSA =  setTimeout(
				function(){
					sendSexAgeEdit( this.value );
				},
				100
			);
		}
		sel.onfocus = function(){
			clearTimeout(client.getBrowseUserObject().timeoutSA);
		}
	}
	selects[0].focus();
}

/*function sendSmokeDrinkEdit( value , detail,obj){
	var data = 	{	type : "saveDetailSD",
					smoke : ((getObject('detailSmoke').checked)? 1 : 0),
					drink : ((getObject('detailDrink').checked)? 1 : 0)
				};
	fetchUserDetails( data );
}*/

function sendSexAgeEdit( value ){
	var data = 	{	type : "saveDetailSA",
					sex : getObject('detailSex').value,
					age : getObject('detailYear').value
				};
	fetchUserDetails( data );
}

function sendHeightWeightEdit( value ){
	var data = 	{	type : "saveDetailHW",
					height : getObject('detailFeet').value+"'"+getObject('detailInch').value+'"',
					weight : getObject('detailWeight').value
				};
	fetchUserDetails( data );
}

function sendDetailsEdit( value , detail,obj){
	var data = 	{	type : "saveDetail",
					detail : detail,
					value : value
				};
	fetchUserDetails( data );
}

function sendInterestEdit( value , interest,obj){
	var data = 	{	type : "saveInterest",
					itype : interest,
					data : value
				};
	fetchUserInterests( data );
}

function showInterests(){
	dh.nodes.interestsList.purge();

	var interests = client.getBrowseUserInterests();

	if(interests && interests.error){
		switch( interests.error ){
			case '6675':
					dh.nodes.interestsList.obj.innerHTML = '<table height="100%" width="100%"><tbody><tr><td height="100%" width="100%" align="center"><img width="100%" height="100%" src="/images/perms/windshield.png" /></td></tr></tbody></table>';
				break;
		}
	}else{
		for( var interestKey in interests  ){
			var iRow = dh.createDHObject("div", "info_" + interestKey, "infoRow", dh.nodes.interestsList.obj);
			createObject( "div", dhNull, 'header', iRow.obj, interestKey + ": ");
			
			var interestValue = interests[interestKey];
			if (isEmpty(interestValue)){
				if (client.isHomeProfile){
					interestValue = "<em>Double click here to edit this field, click out to save.</em>";
				}else{
					interestValue = "n/a";
				}
			}
			
			var obj = createObject( "div", "info_data_"+interestKey, 'info', iRow.obj, interestValue);
			if(client.isHomeProfile()){
				iRow.obj.style.cursor = 'pointer';
				iRow.obj.ondblclick = Function("editInterestInline(this.lastChild,'"+interestKey+"')");
			}
		}
	}

	var detailsList = getObject('detailsList');
	var details = client.getBrowseUserDetails();


	var html = '';
	try{
	if(details && details.error){
		//console.log(details);
		switch( details.error ){
			case '6675':
					html = '<table height="100%" width="100%"><tbody><tr><td height="100%" width="100%" align="center"><img width="190" height="140" src="/images/perms/windshield.png" /></td></tr></tbody></table>';
				break;
		}
	}else{
		//console.log(client.getBrowseUserObject());
		html += 	'<div class="detailsRow" '+
									((client.isHomeProfile())?'ondblclick="editAgeSexInline(this);"':'')+
									'>'+
										'<div class="detailsKey">Sex/Age</div>'+
										'<div '+
										'class="detailsInfo">'+details['sex']+'/'+details['age']+'</div>'+
									'</div>';
		html += 	'<div class="detailsRow" '+
									((client.isHomeProfile())?'ondblclick="editDetailsInline(this,\'status\');"':'')+
									'>'+
										'<div class="detailsKey">Status</div>'+
										'<div '+
	
										'class="detailsInfo">'+details['status']+'</div>'+
									'</div>';
	
		html += 	'<div class="detailsRow" '+
									((client.isHomeProfile())?'ondblclick="editZodiacInline(this);"':'')+
									'>'+
											'<div class="detailsKey">Zodiac</div>'+
											'<div '+
	
											'class="detailsInfo">'+details['zodiac']+'</div>'+
										'</div>';
	
		html += 	'<div class="detailsRow" '+
									((client.isHomeProfile())?'ondblclick="editDetailsInline(this,\'reasons\');"':'')+
									'>'+
											'<div class="detailsKey">Here For</div>'+
											'<div '+
	
											'class="detailsInfo">'+details['reasons']+'</div>'+
										'</div>';
		html += 	'<div class="detailsRow" '+
									((client.isHomeProfile())?'ondblclick="editDetailsInline(this,\'location\');"':'')+
									'>'+
											'<div class="detailsKey">Location</div>'+
											'<div '+
	
											'class="detailsInfo">'+details['location']+'</div>'+
										'</div>';
	/*	html += 	'<div class="detailsRow" '+
									((client.isHomeProfile())?'ondblclick="editSmokeDrinkInline(this,\''+key+'\');"':'')+
									'>'+
											'<div class="detailsKey">Smoke/Drink</div>'+
											'<div '+
	
											'class="detailsInfo">'+((parseInt(details['smoke']))? 'Yes':'No')+'/'+((parseInt(details['drink']))? 'Yes':'No')+'</div>'+
										'</div>';*/
		html += 	'<div class="detailsRow" '+
									((client.isHomeProfile())?'ondblclick="editHeightWeightInline(this);"':'')+
									'>'+
											'<div class="detailsKey">Height/Weight</div>'+
											'<div '+
	
											'class="detailsInfo">'+details['height']+'/'+details['weight']+' lbs.</div>'+
										'</div>';
		html += 	'<div class="detailsRow" '+
									((client.isHomeProfile())?'ondblclick="editDetailsInline(this,\'occupation\');"':'')+
									'>'+
											'<div class="detailsKey">Occupation</div>'+
											'<div '+
	
											'class="detailsInfo">'+details['occupation']+'</div>'+
										'</div>';
	/*	html += 	'<div class="detailsRow" '+
									((client.isHomeProfile())?'ondblclick="editDetailsInline(this,\'children\');"':'')+
									'>'+
											'<div class="detailsKey">Children</div>'+
											'<div '+
	
											'class="detailsInfo">'+details['children']+'</div>'+
										'</div>';
	
		html += 	'<div class="detailsRow" '+
									((client.isHomeProfile())?'ondblclick="editDetailsInline(this,\'education\');"':'')+
									'>'+
											'<div class="detailsKey">Education</div>'+
											'<div '+
	
											'class="detailsInfo">'+details['education']+'</div>'+
										'</div>';
		html += 	'<div class="detailsRow" '+
									((client.isHomeProfile())?'ondblclick="editDetailsInline(this,\'religion\');"':'')+
									'>'+
											'<div class="detailsKey">Religion</div>'+
											'<div '+
	
											'class="detailsInfo">'+details['religion']+'</div>'+
										'</div>';*/
	}
	}catch(ex){/*console.log(ex);*/}

	detailsList.innerHTML = html;

	if( client.isHomeProfile() && !dh.nodes.showEditInterestsButton){
		var showButton = dh.createDHObject("div", "showEditInterestsButton", "managementLink managementLink_statusBar", client.windows.windshield.statusBar.obj, "Double Click Text To Edit Bio", dhNull);
			showButton.onClick = function(){
					if (!client.initWindow('mySettings',function(){client.windows.mySettings.__tab('bio');})){
						return false;
					}else{
						client.windows.mySettings.show();
						client.windows.mySettings.__tab('bio');
						return true;
					}
				}
	} else if( !client.isHomeProfile()){
		try{
			dh.nodes.showEditInterestsButton.destroy();
			delete dh.nodes.showEditInterestsButton;
		}catch(ex){}
	}
}
/*
 * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
 * in FIPS PUB 180-1
 * Version 2.1a Copyright Paul Johnston 2000 - 2002.
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for details.
 */

/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));}
function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}

/*
 * Perform a simple self-test to see if the VM is working
 */
function sha1_vm_test()
{
  return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
}

/*
 * Calculate the SHA-1 of an array of big-endian words, and a bit length
 */
function core_sha1(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << (24 - len % 32);
  x[((len + 64 >> 9) << 4) + 15] = len;

  var w = Array(80);
  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;
  var e = -1009589776;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;
    var olde = e;

    for(var j = 0; j < 80; j++)
    {
      if(j < 16) w[j] = x[i + j];
      else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
      var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
      e = d;
      d = c;
      c = rol(b, 30);
      b = a;
      a = t;
    }

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
    e = safe_add(e, olde);
  }
  return Array(a, b, c, d, e);

}

/*
 * Perform the appropriate triplet combination function for the current
 * iteration
 */
function sha1_ft(t, b, c, d)
{
  if(t < 20) return (b & c) | ((~b) & d);
  if(t < 40) return b ^ c ^ d;
  if(t < 60) return (b & c) | (b & d) | (c & d);
  return b ^ c ^ d;
}

/*
 * Determine the appropriate additive constant for the current iteration
 */
function sha1_kt(t)
{
  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
         (t < 60) ? -1894007588 : -899497514;
}

/*
 * Calculate the HMAC-SHA1 of a key and some data
 */
function core_hmac_sha1(key, data)
{
  var bkey = str2binb(key);
  if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
  return core_sha1(opad.concat(hash), 512 + 160);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert an 8-bit or 16-bit string to an array of big-endian words
 * In 8-bit function, characters >255 have their hi-byte silently ignored.
 */
function str2binb(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
  return bin;
}

/*
 * Convert an array of big-endian words to a string
 */
function binb2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
  return str;
}

/*
 * Convert an array of big-endian words to a hex string.
 */
function binb2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of big-endian words to a base-64 string
 */
function binb2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}

/*`*/
/*************************************************
 *  Attempt a log to firebug - error safe
 */
var DBUG=0;
var XDBG=0;
var ERR=1;
function firebugLog( line ){ try{ console.log(line); } catch (e){ } }
function firebugInfo( line ){ if(DBUG) try{ console.info(line); } catch (e){ } }
function firebugWarn( line ){ if(DBUG) try{ console.warn(line); } catch (e){ } }
function firebugError( line ){ if(ERR) { try{console.trace(); console.error(arguments); } catch (e){ } } }
function firebugDebug( line ){ try{if(DBUG) {console.trace();   console.debug(arguments); }} catch (e){ } }
function firebugExtendedDebug( line ){ try{ if(XDBG){console.trace();  console.debug(arguments); }} catch (e){ } }
function firebugTrace( ){ if(DBUG) try{ console.trace(); } catch (e){ } }
/*!*/


	function splash(){
		window.location.href = "/";
	}
	function webtop(){
		if( url_name ){
			window.location.href = "/" + url_name + "?layer=webtop";
		} else {
			window.location.href = "/user/" + logged_in_id + "?layer=webtop";
		}
	}
	function profile(){
		if( url_name ){
			window.location.href = "/" + url_name;
		} else {
			window.location.href = "/user/" + logged_in_id;
		}
	}


/*
 * The following 2 functions will manage button hovering stylesheets using javascript
 *
 * element.onhover = addClassname
 * element.onout = remove classname ( will only remove the classname specified)
 */
function createJSButtonHover( element, classname, secondaryEnterAction, secondaryLeaveAction ){
	element.onmouseover = function(){ this.className = this.className + " " + classname; if(secondaryEnterAction)secondaryEnterAction(); };
	var reg = eval("/(\\" + classname + ")|(" + classname + ")/");
	element.onmouseout = function(){ this.className = this.className.replace( reg , ''); if(secondaryLeaveAction)secondaryLeaveAction(); };
}
function createJSButton( element, classname, secondaryEnterAction, secondaryLeaveAction, onClick ){
	createJSButtonHover(element, classname, secondaryEnterAction, secondaryLeaveAction);
	if(onClick) element.onclick = onClick;
}
function removeJSButtonHover( element ){
	try{
		delete element.onmouseover;
		delete element.onmouseout;
	}catch(ex){
		element.onmouseover = null;
		element.onmouseout = null;
	}
}

function JSTip( HTMLElement, htmlTip ){

	HTMLElement.onmouseover = function () {

		var jsTip = getObject('jsTip');
		jsTip.innerHTML = htmlTip;
		registerTipObject( jsTip , 20, -10);

	};
	HTMLElement.onmouseout = unregisterToolTip;

}

//some functionality functions
var activityTimers = {};
function resetActivity (timerKey, activityTimeout, timeoutCallback ){
	try{ clearTimeout( activityTimers[timerKey] ); } catch (ex){}
	activityTimers[timerKey] = setTimeout(timeoutCallback, activityTimeout);
}
function cancelActivityTimer(timerKey){
	try{ clearTimeout( activityTimers[timerKey] ); } catch (ex){}
	delete activityTimers[timerKey];
}

function resetActivityField(timerKey, activityTimeout, timeoutCallback,field){
	var func = function(){timeoutCallback(field)};
	resetActivity (timerKey, activityTimeout, func )
}

/* a little backward compatability for the kaila yu theme */
function insertRealText(layerID, style, text){
	return createObject("div", layerID, style, 'contest_profile', text);
}
/*************************************************
 *  Generate a user avatar block in parentDiv
 *
 * 	avatarInfo = object
 * 		{
 * 			fileName,
 * 			userName,
 * 			userId,
 * 			sex
 * 		}
 *
 ************************************************/
function showImage(url, showBorder){
	if (showBorder == undefined) showBorder = true;
	//refernece our exisiting objects
	var parent = document.getElementById('windowspace');
//	var ref  = document.getElementById('outWrap');
	var imageMatte = new matte("imagePopup", .5, true, false);
	var styleTag = "max-width:" + ( dh.viewportW - 50) + "px;" +
				   "max-height:" + ( dh.viewportH - 20) + "px;";

	if(!showBorder) styleTag += "border: 0px;";
	imageMatte.content.innerHTML = "<table class='f'><tr><td valign='middle' align='center'><img class='imagePopupImage' style=\"" + styleTag +"\" src='" + url + "'></td></tr></table>";

	//set our viewing flag
	viewingImage = true;
}
/************************
	Backgorund Matte Gen.
************************/
var currentMatte = null;
function matte(theme, opacity, clickToExit, followViewport){
	if( getObject("popupWrap") ) return; //only 1 popup at a time

 	this.wrap = createObject("div", 'popupWrap', "popupWrap_" + theme , getObject('windowspace') , dhNull);
	this.wrap.style.width = dh.viewportW + 'px';
	this.wrap.style.height = dh.documentH + 'px';

	this.bg = createObject("div", 'popupMatte', "popupMatte_" + theme , this.wrap, dhNull);
	this.bg.style.width = dh.viewportW + 'px';
	this.bg.style.height = dh.documentH + 'px';
	setOpacity(this.bg, opacity);

	this.content = createObject("div", 'popupContent', "popupContent_" + theme , this.wrap, dhNull);
	this.content.style.top = dh.scrollTop + "px";
	this.content.style.height = (dh.viewportH - dh.nodes.header.getH()) + 'px';
	this.content.style.width = dh.viewportW + 'px';

	this.onclick = null;
	this.onunload = null;

	//on click callbacks
	this.wrap.PopObj = this;
	this.bg.PopObj = this;
	this.content.PopObj = this;

	this.wrap.onclick = function(e){ this.PopObj.clickHandler(); };
	this.bg.onclick = function(e){ this.PopObj.clickHandler(); };
	this.content.onclick = function(e){ this.PopObj.clickHandler(); };
	this.quickExit = clickToExit;

	if(followViewport){
		dh.addScrollEvent("popupMove", this.scrollMatteContent);
	}
};

matte.matte_clear = "";
matte.matte_white = "#FFFFFF";
matte.matte_red = "#ff7777";
matte.matte_orange = "#ff9900";
matte.matte_yellow = "#ffff00";
matte.matte_green = "#7ed67e";
matte.matte_blue = "#7e9cff";
matte.matte_violet = "#b566ff";
matte.matte_black = "#000000";

matte.prototype.clickHandler = function(e){
	if(this.onclick) this.onclick(e);
	if(this.quickExit) matte.hideMatte();
}
matte.hideMatte = function (){
	var matteWrap = getObject("popupWrap");
	if(matteWrap){
		matteWrap.parentNode.removeChild(matteWrap);
		dh.removeScrollEvent("popupMove");
		if(matteWrap.PopObj.onunload) matteWrap.PopObj.onunload();
	}
}
matte.fadeMatte = function (){
	//TODO
}
matte.prototype.scrollMatteContent = function(){
	var img  = getObject('popupContent');
	newTop = ( dh.scrollTop + dh.viewportH > dh.documentH) ? dh.documentH -  dh.viewportH : dh.scrollTop;
	img.style.top = newTop + "px";
}
function ObjStack(){
	this.data = new Array();
	this.length = 0;
}

ObjStack.prototype = {
	data:null,
	length:0,
	peek : function(){
		return this.data[this.length - 1];
	},
	pop : function(){
		this.length--;
		return this.data[this.length];
	},
	push : function( obj ){
		this.data[this.length] = obj;
		this.length++;
	}
}

//gives the uurl to the avatar generator
function getAvatarURL( userID ){ return "/api/servlets/images?user_id=" + userID + "&type=avatar"; }

function displayUserAvatar( parentDiv, avatarInfo, showDetails, showUserName, allowSpecialFriendSelection ,addToTop) {
	//userId, userName, avatarName, displayPopUp, specialFriend, allowSpecialFriendSelection, showUserName, draggable, useJavascriptToView, sex){

	//defaults to allow popup details
	showDetails = 					( isEmpty(showDetails) ) ? 					true : showDetails;
	showUserName = 					(isEmpty(showUserName)) ? 					true : showUserName;
	allowSpecialFriendSelection = 	(isEmpty(allowSpecialFriendSelection)) ? 	true : allowSpecialFriendSelection;

	var now = new Date().getMilliseconds();
	var userId = avatarInfo.user_id;

	if (avatarInfo && avatarInfo.userName){
		var displayName = (avatarInfo.userName.length < 11) ? avatarInfo.userName : avatarInfo.userName.substring( 0, 11) + '...';
	}else{
		var displayName = '<em>No Name</em>';
	}
	///api/servlets/images?type=manual&photo_id=4541&size=100
	var avatarSrc = getAvatarURL(userId);
					/*case else*/ "/images/avatar_unisex.jpg";
	//var avatarSrc = "/api/servlets/images?type=manual&photo_id=4541&size=100";

	var avatar = 		createObject("div", dhNull, "avatar", 			dhNull,		dhNull);

	// online icon
	var online = parseInt(avatarInfo.online);
	if (online){
		var onlineNow = createObject('div', dhNull, "avatarOnlineNow", avatar, dhNull);
	}

	if(addToTop){
		parentDiv.insertBefore(avatar,parentDiv.firstChild);
	}else{
		parentDiv.appendChild(avatar);
	}
	if(showUserName){
		var avatarHeader = 	createObject("div", dhNull, "avatarHeader", 	avatar,			displayName);
	}
	var avatarDHWrapper = dh.createDHObject("div", "avatar_" + userId + "_" + now, "avatarWrapper", 	avatar,			dhNull, dragdrop + cloneOnDrag + draggroup + "avatar");
	var link = 			createObject("a", 	dhNull, dhNull, 			avatarDHWrapper.obj,	dhNull);

	avatarDHWrapper.setBgImage( avatarSrc+"&rand="+((Math.random()).toFixed(5)) );
	var avatarImg =	createObject("img", dhNull, 'avatarHitArea', link, dhNull); //dragdrop + cloneOnDrag + maxCloneCount + "1");
	avatarDHWrapper.setValue(userId);
	//avatarDHImg.setImage(avatarSrc);
	avatarImg.src = ecirkitImagesURL + 'spacer.gif';

	avatarDHWrapper.onGrab = function(){ client.hideAvatarDetails(userId); };

	avatarImg.userid = userId;
	avatar.userid = userId;

	if(showDetails){
		avatarImg.onmouseover = function () {
			clearTimeout( client.avatarDetailsTimeoutRef );
			if(client.viewingDetails) client.hideAvatarDetails(client.viewingDetails);
			client.waitingForDetails = userId;
			setTimeout(
				function () {
					client.initAvatarDetails( userId, avatarImg );
				},
				0);
		};
		avatarImg.onmouseout = client.avatarDetailsTimeout();
	}

	if (allowSpecialFriendSelection) {
		//avatarHeader.onclick = function () { chooseAsBestFriend(userId); };
		avatarHeader.style.cursor = 'pointer';
	}

	avatarImg.onclick = function () { client.browseUser(this.userid);  return false;};
	//link.href = '/profile.php';

	return avatarDHWrapper;
}

/****************************************
 	Mouse cursor interaction - tool tips
****************************************/
var tipObject = null;
var hlpOff = [0,0]; //general offset
var adjOff = [0,0]; //adjOff = adjustmentOffset

function positionToolTip(){
	//check for document bounds
	if( getW(tipObject)+dh.mouseX+parseInt(hlpOff[0]) > dh.documentW)
		{ adjOff[0]=(-1*getW(tipObject)-(hlpOff[0]*2)); }
	else if( adjOff[0]!=0 ) adjOff[0]=0;
	if( getH(tipObject)+dh.mouseY+parseInt(hlpOff[1]) > dh.scrollTop +  dh.viewportH - 100)
		{ adjOff[1]=(-1*getH(tipObject)-(hlpOff[1]*2)); }
	else if( adjOff[1]!=0 ) adjOff[1]=0;
	tipObject.style.left = dh.mouseX + hlpOff[0] + adjOff[0] + "px";
	tipObject.style.top = dh.mouseY + hlpOff[1] + adjOff[1] + "px";
}
function registerTipObject(obj, xOffset, yOffset){
	if(tipObject != null){ 	hideObject(tipObject); } //quick switch
	else {dh.addMouseMoveEvent("tooltip", positionToolTip);}	//new tooltip, add the mouse event

	tipObject = getObject(obj);
	hlpOff[0] = parseInt(xOffset);
	hlpOff[1] = parseInt(yOffset);
	showObject(tipObject);
	positionToolTip();
}
function unregisterToolTip(){
	hideObject(tipObject);
	tipObject = null;
	dh.removeMouseMoveEvent("tooltip");
}

/****************************
	Cookie Functions
****************************/
function setCookie(name, value, expires, path, domain, secure) {
  var curCookie = name + "=" + escape(value) + ((expires) ? "; expires=" + expires.toGMTString() : "") + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : "");
  document.cookie = curCookie;
}
function deleteCookie(name, path, domain) {
	if (getCookie(name)) document.cookie = name + "=" + ((path)? ";path=" + path : "") + ((domain)? ";domain=" + domain : "" ) + ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}
function getCookie(name) {
	var start = document.cookie.indexOf(name + "=");
	var len = start + name.length + 1;
	if ((!start) && (name != document.cookie.substring(0, name.length))) return null;
	if (start == -1) return null;
	var end = document.cookie.indexOf(";", len);
	if (end == -1) end = document.cookie.length;
	return unescape(document.cookie.substring(len, end));

}
// browse
	function getRadioValue(/* String */ radioGroupID){
		var elements = document.getElementsByName(radioGroupID);
		if (!elements) return;
		for (var i in elements){
			if (elements[i].checked){
				return elements[i].value;
			}
		}
	}

function formatDateTime(string){

	if (!string){
		return '0000-00-00';
	}
	return string.replace(/(.*)-(.*)-(.*)\s(.*)/,'$2-$3-$1');
}

function getFckContents(textarea){
	var oEditor = FCKeditorAPI.GetInstance(textarea) ;
	return oEditor.GetXHTML(true);
}
// each element of the option array (optAry) is an object with two fields "text" and "value"

function customSelect( optAry , onChange ){
	var html = '<div class="cusSelWrap">'+
					'<input type="hidden" value="" />'+
					'<div class="cusSelValueRow">'+
						'<div class="cusSelValue"></div>'+
						'<div class="cusSelDropBtn" onmousedown="clearTimeout(this.parentNode.nextSibling.lastChild.value);" onclick="if(this.parentNode.nextSibling.style.display == \'none\'){showObject(this.parentNode.nextSibling);this.parentNode.nextSibling.lastChild.focus();Y(this.parentNode.nextSibling,getH(this));this.parentNode.nextSibling.scrollTop = 0;}else{hideObject(this.parentNode.nextSibling);if(this.parentNode.parentNode.sel){this.previousSibling.innerHTML = this.parentNode.parentNode.sel.innerHTML}}"></div>'+
					'</div>'+
					'<div class="cusSelOptWrap" style="display:none;z-index:1800;">';
	for(var x = 0; x < optAry.length; x++){
		html +=			'<div class="cusSelOptRow">'+
							'<input type="hidden" value="'+((optAry[x].value)? optAry[x].value : optAry[x].text )+'"/>'+
							'<div class="cusSelOptText"'+
							'onmouseover="this.className += \' cusSelHL\';'+
							'this.parentNode.parentNode.parentNode.childNodes[1].childNodes[0].innerHTML = this.innerHTML;'+
							'"'+
							'onmouseout="this.className = this.className.replace(/(cusSelHL)|(\\scusSelHL)/g,\'\')"'+
							'onmousedown="'+
								'this.parentNode.parentNode.parentNode.childNodes[0].value = this.previousSibling.value;'+
								'if(this.parentNode.parentNode.parentNode.sel){this.parentNode.parentNode.parentNode.sel.onmouseout();}'+
								'this.parentNode.parentNode.parentNode.sel = this;'+
								'this.parentNode.parentNode.parentNode.childNodes[1].childNodes[0].innerHTML = this.innerHTML;'+
								'this.onmouseover();'+
								((onChange)? onChange+'(this.parentNode.parentNode.parentNode);"' : '"')+
							'>'+optAry[x].text+'</div>'+
						'</div>';
	}
			html+=		'<input type="text" '+
						'style="height:0px;width:0px;border:none;padding:0px;margin:0px;background:none;" '+
						'onkeypress="testCusSelKey( event , this.parentNode.parentNode);" '+
						'onblur="var input = this;this.value=setTimeout(function(){input.parentNode.parentNode.childNodes[1].childNodes[1].onclick();},200);" />'+
					'</div>'+
				'</div>';

	return html;
}

function testCusSelKey( e , cusSel){
	if(!e) var e = window.event;

	if(!cusSel.sel)cusSel.sel = cusSel.childNodes[2].childNodes[0].childNodes[1];
	switch((e.keyCode || e.which)){
		//up
		case 38:
			var prev = (cusSel.sel.parentNode.previousSibling)? cusSel.sel.parentNode.previousSibling.childNodes[1]: cusSel.sel.parentNode.parentNode.lastChild.previousSibling.childNodes[1];
			cusSel.sel.onmouseout();
			cusSel.sel = prev;
			cusSel.sel.onmouseover();
		break;
		//down
		case 40:
			var next = (cusSel.sel.parentNode.nextSibling.nextSibling)? cusSel.sel.parentNode.nextSibling.childNodes[1]: cusSel.sel.parentNode.parentNode.firstChild.childNodes[1];
			cusSel.sel.onmouseout();
			cusSel.sel = next;
			cusSel.sel.onmouseover();
		break;
		//enter
		case 13:
			cusSel.sel.onmousedown();
			cusSel.childNodes[0].focus();
		break;
	}
	cusSel.childNodes[2].scrollTop = parseInt(cusSel.sel.offsetTop - getH(cusSel.childNodes[2]) / 2);
}

function getCusSelVal( cusSel ){
	return cusSel.childNodes[0].value;
}
function setCusSelVal( cusSel , value){
	var values = cusSel.childNodes[2].getElementsByTagName("input");
	var limit = (values.length - 1);
	for(var x = 0; x < limit; x++){
		if(values[x].value == value){
			values[x].nextSibling.onmousedown();
		}
	}
}
/*************************************************
*
* 		ePromptit
*
*
**************************************************/
/*
function ePromptit( msg, okFunc, noFunc, callback){
	this.msg = msg;
	this.okFunc = okFunc;
	this.noFunc = noFunc;
	this.callback = callback;
}
ePromptit.prototype = {
	msg:null,
	okFunc:null,
	noFunc:null,
	dhObj:null,
	callback:null,

	init : function(){
		this.build();
	},

	build : function (){
		var thisPrompt = this;

		this.dhObj = dh.createDHObject("div",this.msg,"filePop ePromptit",document.body,"",hidden);

		var htmlObj = this.dhObj.obj;
		var titleBar = createObject('div', dhNull, 'filePopTitleBar tal', htmlObj, 'ePromptit');

		var contentWrapper = createObject('div', dhNull, 'filePopContentWrapper', htmlObj);
		var msg = createObject("h2",dhNull,dhNull,contentWrapper,this.msg);

		var promptFooter = createObject('div', dhNull, 'filePopFooter', htmlObj);
		var ok = document.createElement("input");
			ok.type = "button";
			ok.value = "OK";
			ok.onclick = function(){thisPrompt.ok()};
		var no = document.createElement("input");
			no.type = "button";
			no.value = "No Way";
			no.onclick = function(){thisPrompt.no()};

		promptFooter.appendChild(ok);
		promptFooter.appendChild(no);

		client.showWorkspaceMatte();
		this.dhObj.centerViewport();
		this.dhObj.show();
	},

	destroy : function (){
		this.dhObj.destroy();
		client.closeMatte();
	},

	ok : function (){
		this.destroy();
		try{
			this.okFunc();
		}catch(e){
			firebugError("Could not call 'Ok' function : "+ e);
		}
		if(this.callback){
			this.callback();
		}
	},

	no : function (){
		this.destroy();
		if(this.noFunc){
			try{
				this.noFunc();
			}catch(e){
				firebugError("Could not call 'Cancel' function : " + e);
			}
		}
		if(this.callback){
			this.callback();
		}
	}
};
*/

/*********************************************
*
* 		Resize Functions
*
*********************************************/

function fillHorizontally( obj ){
	if(!obj)return -1;
	else obj.style.width = "0px";

	var temp = obj;
	var totalW = getInnerW(obj.parentNode);
	var offSetW = 0;
	var w = 0;

	while(temp =  temp.previousSibling){
		var w = getW(temp);

		offSetW += w;
	}temp = obj;
	while(temp = temp.nextSibling){
		var w = getW(temp);

		offSetW += w;
	}
	/*if(!(temp = dh.$(obj.id))){
		temp = dh.addObject(obj.id,none);
	}*/

	var newW = totalW - offSetW;
	obj.style.width = newW+"px";
	//temp.resizeTo(newW,dhNull);
	return newW;
}
function fillVertically( obj ){
	if(!obj)return -1;
	else obj.style.height = "0px";

	var temp = obj;
	var totalH = getH(obj.parentNode);
	var offSetH = 0;
	var w = 0;

	while(temp =  temp.previousSibling){
		var w = getH(temp);

		offSetH += w;
	}temp = obj;
	while(temp = temp.nextSibling){
		var w = getH(temp);

		offSetH += w;
	}
	/*if(!(temp = dh.$(obj.id))){
		temp = dh.addObject(obj.id,none);
	}*/

	var newH = totalH - offSetH;
	obj.style.height = newH+"px";
	//temp.resizeTo(dhNull,newH);
	return newH;
}

function prepDate( inDate ){
	if(!inDate)return '';
	var date = inDate.replace(/(\d\d(\d\d))-(\d\d)-(\d\d).*/,'$3/$4/$2');
	var hour = parseInt(inDate.replace(/.*(\d\d):(\d\d):(\d\d)/,'$1'));
	var ampm = '';
	if(hour > 12 && hour < 24){
		hour = hour - 12;
		ampm = "PM";
	}else{
		ampm = "AM";
	}
	if(hour == 0){
		hour = 12;
	}else if(hour == 12){
		ampm = "PM";
	}
	time = inDate.replace(/.*(\d\d):(\d\d):(\d\d)/,hour+':$2');

	return  time+" "+ampm+" "+date;
}


/**
 * Build a flash object
 * createObjectTag  defaults to true
 */
function createFlash(container, url, id, width, height, transparent, flashvars , createObjectTag, allowFullScreen, flashAlign ){

	//prevent errors
	if(createObjectTag == dhNull ) createObjectTag = true;

	var obj = '<object' + ((window.ActiveXObject)? ' id="' + id + '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" data="' + url + '"' : '');
	obj += ' width="' + width + '" height="' + height + '">';
	var extraParams = '';
	var extraAttributes = '';
	if( transparent ){
		extraParams += '<param name="wmode" value="transparent">';
		extraAttributes += 'wmode="transparent"';
	}

	if( allowFullScreen ){
		extraParams += '<param name="allowFullScreen" value="true" />';
		extraAttributes += ' allowFullScreen="true" ';
	}

	if (flashAlign) {
		extraParams += '<param name="salign" value="TL" />';
		extraAttributes += ' salign="TL" ';
	}
//removed - but works in key - value pairs a.k.a. objects a.k.a. associative arays;
//	for(var key in params){
//		extraParams += '<param name="' + i + '" value="' + params[key] + '">';
//		extraAttributes += ' ' + i + '="' + params[key] + '"';
//	}

	var embed = '<embed '+((!isEmpty(flashvars))? 'flashvars="'+flashvars+'" ': '')+'id="' + id + '" src="' + url + '" type="application/x-shockwave-flash" width="' + width + '" height="' + height + '"';
	embed += extraAttributes + '></embed>';

	var html =
		( createObjectTag ? obj + '<param name="movie" value="' + url + '">' + extraParams +
							(!isEmpty(flashvars)? '<param name="flashvars" value="' + flashvars + '" />' : '')+ embed + '</object>'
		:					embed);
	if(container)
		container.innerHTML = html;

	return html;
}

// builds and returns a copy of the array in the parameters
function getArrayCpy(ary){
	var temp = new Array();
	for(key in ary){
		temp.push(ary[key]);
	}
	return temp;
}
function loadInBrowser(data){
	client.initWindow('snapBrowser',function(){client.windowFunctions.snapBrowser.addTab(data)});
}

function snapHref(link){
	loadInBrowser({Url:link,title:link.replace(/^(((ht|f)tp(s?))\:\/\/)?(www.|[a-zA-Z].)([a-zA-Z0-9\-\.]+)\.(com|edu|gov|mil|net|org|biz|info|name|museum|us|ca|uk)(\:[0-9]+)*(\/($|[a-zA-Z0-9\.\,\;\?\'\\\+&%\$#\=~_\-]+))*$/,'$6').substr(0,8),description:link.substr(0,20)});
}

function descriptionPop(msg){
	var obj = null;
		if(!(obj = getObject("urlPopUp"))){
			obj = createObject("div","urlPopUp",dhNull,getObject("canvas"));
		}
		obj.innerHTML = prepMessage(msg,true,true,false);
		registerTipObject(obj, -68, 25);
}
function isVisible( thisBeacon ){
	var d = thisBeacon.style.display;
	var v = thisBeacon.style.visibility;

	if(d == "none" || v =="hidden" || !getW(thisBeacon) ){
		return false;
	}else{
		return true;
	}
}

function getSelectBoxValue(selectId){
	var select = getObject(selectId);
	return select[select.selectedIndex].value;
}

function showPrivacyDesc(x,y,h,obj,row,msgNum){
	var msg = '';
	var titleBG = row;
	var BGColor = '';
	obj.innerHTML = '';
	switch(msgNum){
		case 0:
			msg = 'Choosing this setting means that the entire internet has access to this area of your eCirkit account.';
			BGColor="#10BF13";
			break;
		case 1:
			msg = 'Choosing this setting means that all logged in eCirkit users have access to this area of your eCirkit account.';
			BGColor="#4FBFA1";
			break;
		case 2:
			msg = 'Choosing this setting means that only your eCirkit Contacts have access to this area of your eCirkit account.';
			BGColor="#4B66BF";
			break;
		case 3:
			msg = 'Choosing this setting means that only the groups you select will have access to this area of your eCirkit account.';
			BGColor="#977CBF";
			break;
		case 4:
			msg = 'Choosing this setting means that only you have access to this area of your eCirkit account.';
			BGColor="#BF3D36";
			break;
	}
	//X(titleBG,0);
	//Y(titleBG,y);
	//W(titleBG,x+ 10);
	//H(titleBG,h);
	titleBG.style.background = BGColor;
	//showObject(titleBG);

	X(obj,x+3);
	Y(obj,y);
	W(obj,125);
	obj.style.padding="10px";
	obj.style.textAlign="center";

	obj.style.border="1px solid black";
	//obj.style.background="dark red";

	obj.innerHTML = msg;
	obj.titleBG = titleBG;
	showObject(obj);
}
function hidePrivacyDesc(obj){
	hideObject(obj);
	obj.titleBG.style.background = "none";
}

function aryIndexOf( ary, obj){
		for(var x = 0; x < ary.length;x++){
			if(obj == ary[x])
				return x;
		}

		return -1;
}

function fetchGroups(callback){
	ajax.post('/api/processors/groups',{type:'getGroups'},
		function(conn){
			if(conn && conn.responseObject){
				client.data.userInfo.groups = conn.responseObject;
			}else{
				client.data.userInfo.groups = [];
			}
			if(callback)callback();
		},
		function(conn){
			client.data.userInfo.groups = [];
			if(callback)callback();
		});
}

function fetchGroupData(gIndex,callback){
	var group = client.data.userInfo.groups[gIndex];
	var gID = group.user_group_id;
	ajax.post('/api/processors/groups',{type:'getGroupMembers',group_id:gID},
		function(conn){
			var data = null;
			if(conn && conn.responseObject){
				data = conn.responseObject;
			}else{
				data = [];
			}
			if(callback)callback(gIndex,data);
		},
		function(conn){
			if(callback)callback(gIndex,[]);
		});
}

function manageGroups(){
	if(!client.windowFunctions.mySettings){
		client.initWindow('mySettings',function(){client.windowFunctions.mySettings.selOpt = 5;});
	}else{
		client.windows.mySettings.show();
		client.windowFunctions.mySettings.optList.childNodes[5].onclick();
	}
}
var sysClock = null;
var sysClockDock = null;
var sysClock_t = null;
function updateSysClock(){
	clearTimeout(sysClock_t);
	var time = new Date();
	var hour = time.getHours();
	var minute = time.getMinutes();
	var post = '';

	if(hour==0){post=" AM";hour=12}
	else if(hour <= 11){post=" AM"}
	else if(hour == 12){post=" PM";hour=12}
	else if(hour >= 13){post=" PM";hour-=12}

	if(minute < 10)minute = "0"+minute;

	client.time = hour+":"+minute+" "+post;

	/*try{
		sysClock.innerHTML = client.time;
	}catch(ex){}*/
	try{
		sysClockDock.innerHTML = client.time;
	}catch(ex){console.log(ex);}

	sysClock_t = setTimeout(updateSysClock,60000);
}

function setAdBackground(windowName, advertiserId, imageName, opacity, x, y){

	if (!parseInt(client.windowSettings[windowName].showAdBackground)){
		return false;
	}

	if (!windowName) return false;
	if (!advertiserId) return false;
	if (!imageName) return false;
	if (!opacity) opacity = 1;
	if (!x) x = 100;
	if (!y) y = 100;

	var bg = getObject('dhWin_' + windowName + '_bg2');
	bg.style.background = '#FFFFFF url(/images/ads/' + advertiserId + '/' + imageName + ') no-repeat scroll';
	bg.style.opacity = opacity;
	bg.style.mozOpacity = opacity;
	bg.style.filter = 'alpha(opacity=' + opacity.replace('.', '') + ')';
	bg.style.backgroundPosition = x + '% ' + y + '%';

	return true;
}

function setAdBackgroundOpacity(windowName, opacity){
	var bg = getObject('dhWin_' + windowName + '_bg2');
	bg.style.opacity = opacity;
	bg.style.mozOpacity = opacity;
	bg.style.filter = 'alpha(opacity=' + opacity.replace('.', '') + ')';
}

function setAdWindowTitle(windowName, adTitle){

	if (!parseInt(client.windowSettings[windowName].showAdSponsoredBy)){
		return false;
	}

	if (!windowName) return false;
	if (!adTitle) return false;

	var oldTitle = client.windows[windowName].getTitle();
	var titlePieces = oldTitle.split(' - ');
	client.windows[windowName].setTitle(titlePieces[0] + ' - <span class="windowSponsoredBy">Sponsored by ' + adTitle + '</span>');
}

function setAdWindowHyperLink(windowName, url, urlText){

	if (!parseInt(client.windowSettings[windowName].showAdUrl)){
		return false;
	}


	if (!windowName) return false;
	if (!url) return false;
	if (!urlText) return false;

	var urlHtml = '<a onclick="loadAdSite(\'' + windowName + '\', \'' + url + '\');" href="#;">' + urlText + '</a>';

	var obj = getObject("dhWin_" + windowName + "_StatusAd");
	if (obj){
		obj.innerHTML = urlHtml;
	}
}

function loadAdSite(windowName, url){
	if (!windowName) return false;
	if (!url) return false;

	snapHref(url);

	ajax.post('/api/processors/ads',{type:'loadAdSite', window: windowName},
		function(conn){		},
		function(conn){		}
	);
}
var FileSchema = {};
var FileFunctions = {};
var FileContext = {};
var FileMenu = {};


/**********************************************
 * 
 * 			Bookmark Info
 * 
 **********************************************/
 
FileSchema['bookmark'] = {
			'Description':25,
			'Date Added':15,
			'Url':40,
			'Edit':17
		};
FileFunctions['bookmark'] = {
			"dir": {
					"Description":{
						"click":"expand"
					}
				},
			"file": {
					"Url":{
						"click":"loadInBrowser",
						"mouseover":"showBookmarkDescription",
						"mouseout":"hideBookmarkDescription"
					},
					"Description":{
						"click":"loadInBrowser"
					}
				},
			"PrepRow":"prepBookmarkRow"
		};
FileContext['bookmark'] = {
			"dir":{
					"New Bookmark":"editBookmark",
					"New Folder":"mkDir",
					"Rename Folder":"renameFile",
					"Move Folder":"moveFolder",
					"Delete Folder":"deleteFile",
					"Refresh":"loadFiles"
				},
			"file":{
					"Edit Bookmark":"editBookmark",
					"Move Bookmark":"moveFolder",
					"Delete Bookmark":"deleteFile",
					"Refresh":"loadFiles"
				},
			"list":{
					"New Bookmark":"editBookmark",
					"New Folder":"mkDir",
					"Refresh":"loadFiles"
				}
		};
FileMenu['bookmark'] = {
	"mkDir":{
		"id":"FolderAdd",
		"value":'<div class="iconText">'+
						'<div class="icon24 plusSquareTan24 "></div>'+
						'<div class="tanIconText" style="line-height:26px;">ADD FOLDER</div>'+
					'</div>',
		"func":"mkDir"
	},
	"touch":{
		"id":"FileAdd",
		"value":'<div class="iconText">'+
						'<div class="icon24 plusCircleTan24"></div>'+
						'<div class="tanIconText" style="line-height:26px;">ADD BOOKMARK</div>'+
					'</div>',
		"func":"editBookmark"		
	},
	"backToB":{
		"id":"backToB",
		"value":'<div class="iconText">'+
						'<div class="icon24"></div>'+
						'<div class="tanIconText" style="line-height:26px;">BACK TO BROWSER</div>'+
					'</div>',
		"func":"backToB"		
	}
};		

/**********************************************
 * 
 * 			Quick Vault Info
 * 
 **********************************************/
		
FileSchema['quickvault'] = {
			"File Name":100,
			"Date Added":0,
			"Size":0,
			"Edit":0
		};
FileFunctions['quickvault'] = {
			"dir": {
					"File Name":{
						"click":"expand"
					}
				},
			"file": {

				},
			"PrepRow" : "prepQuickVaultRow"
		};
FileContext['quickvault'] = {
			"dir":{
					"Refresh":"loadFiles",
					"Folder Details":"displayDetails"
				},
			"file":{
					"File Details":"displayDetails",
					"Refresh":"loadFiles"
				},
			"list":{
					"Refresh":"loadFiles"
				}
		};
		
/**********************************************
 * 
 * 			Vault Info
 * 
 **********************************************/
		
FileSchema['vault'] = {
			"File Name":50,
			"Date Added":15,
			"Size":15,
			"Locked":5
		};
FileFunctions['vault'] = {
			"dir": {
					"File Name":{
						"click":"editVaultFile"
					},
					"Edit":{
					}
				},
			"file": {
				"File Name":{
						"dblclick":"inlineEdit"
					}
				},
			"PrepRow" : "prepVaultRow"
		};
FileContext['vault'] = {
			"dir":{
					"New Folder":"mkDir",
					"Rename Folder":"renameFile",
					"Move Folder":"moveFolder",
					"Delete Folder":"deleteFile",
					"Refresh":"loadFiles",
					"Folder Details":"displayDetails"
				},
			"file":{
					"Edit File Info":"editVaultFile",
					"Move File":"moveFolder",
					"Delete File":"deleteFile",
					"File Details":"displayDetails",
					"Refresh":"loadFiles"
				},
			"list":{
					"New Folder":"mkDir",
					"Refresh":"loadFiles"
				}
		};
FileMenu['vault'] = {
	"mkDir":{
		"id":"FolderAdd",
		"value":	'<div class="iconText">'+
						'<div class="icon24 plusSquareTan24"></div>'+
						'<div class="tanIconText" style="line-height:26px;">ADD FOLDER</div>'+
					'</div>',
		"func":"mkDir"
	}/*,
	"touch":{
		"id":"FileAdd",
		"value":"[+] ADD FILES",
		"func":"showFileAdd"		
	}*/
};

/**********************************************
 * 
 * 			Photo Carousel Info
 * 
 **********************************************/
		
FileSchema['photos'] = {
			"Photo Name":100,
			"Date Added":0,
			"Url":0,
			"Size":0
		};
FileFunctions['photos'] = {
			"dir": {
					"Photo Name":{
						"click":"expand"
					},
					
					"Icon":{
						"click":"openFolder",
						"mouseover":"highlightImg",
						"mouseout":"dimImg"
						
					}
				},
			"file": {
					"Icon":{
						"click":"showImage",
						"mouseover":"remarkPopUp",
						"mouseout":"remarkPopDown"
					},
					"Photo Name":{
						"click":"showImage"
						
					}
				}
		};
/*FileContext['photos'] = {
			"dir":{
				},
			"file":{
				},
			"list":{
				}
		};*/
		
/**********************************************
 * 
 * 			Photos Manager Info
 * 
 **********************************************/
		
FileSchema['photosMan'] = {
			"Photo Name":100,
			"Date Added":0,
			"Url":0,
			"Size":0
		};
FileFunctions['photosMan'] = {
			"dir": {
					"Photo Name":{
						"click":"expand"
					},
					
					"Icon":{
						"click":"openFolder"
					}
				},
			"file": {
					"Icon":{
						"click":"editPhoto"
					},
					"Photo Name":{
						"click":"showImage"
					}
				}
		};
FileContext['photosMan'] = {
			"dir":{
					"New Gallery":"mkDir",
					"Rename Gallery":"renameFile",
					"Move Gallery":"moveFolder",
					"Delete Gallery":"deleteFile",
					"Refresh":"loadFiles",
					"Gallery Details":"displayDetails"
				},
			"file":{
					"Picture Details":"displayDetails",
					"Move Picture":"moveFolder",
					"Delete Photo":"deleteFile",
					"Refresh":"loadFiles"
				},
			"list":{
					"Refresh":"loadFiles"
				}
		};
FileMenu['photosMan'] = {
	"mkDir":{
		"id":"GalleryAdd",
		"value":"[+] ADD GALLERY",
		"func":"mkDir"
	},
	"touch":{
		"id":"FileAdd",
		"value":"[+] ADD PHOTOS",
		"func":"showPhotoUpload"		
	}
};

/**********************************************
 * 
 * 			Account Settings Info
 * 
 **********************************************/

FileSchema['account'] = {
			"col1":45,
			"col2":45
		};
FileFunctions['account'] = {
			"dir": {
					"col1":{
						"click":"expand"
					}
				},
			"file": {

				},
			"PrepRow" : "prepBackground"
		};
FileContext['account'] = {
			"dir":{
				"Refresh":"loadFiles"
				},
			"file":{
				"Refresh":"loadFiles"
				},
			"list":{
					"Refresh":"loadFiles"
				}
		};
function fetchUserBookmarks(){
	if(client.data.profileBookmarks)return true;
	var post = {
		type:"getBookmarks",
		i:client.getBrowseUserID()
	};
		ajax.post("/api/processors/user",
			post,
	 		function( conn ){
	 			if(conn && conn.responseObject && conn.responseObject.error){
					switch( conn.responseObject.error ){
						case '6675':
								getObject('userBookmarksCanvas').innerHTML = '<table height="100%" width="100%"><tbody><tr><td height="100%" width="100%" align="center"><img src="/images/perms/windshield.png" width="100%" /></td></tr></tbody></table>';
								return false;
							break;
					}
				}else if(conn.responseObject){
		 				client.windows.windshield.setLoading(true);
		 				client.windows.windshield.setStatus("Building Bookmarks . . .");
		 				client.data.profileBookmarks = conn.responseObject;
		 				buildBookmarkPane( dh.nodes.userBookmarksCanvas , client.data.profileBookmarks,true);
	 			}else{
	 				
	 			}
	 		},
	 		null,
	 		client.windows.windshield);
}
function buildBookmarkPane( dhCont , dataList,purge){
	if(purge)dhCont.purge();
	var buildTo = null;
	if((buildTo = dh.nodes.hiddenBook)){
		buildTo.destroy();
	}
	setTimeout(
		function(){
			buildTo = dh.createDHObject("div","hiddenBook","r o f",canvasStorage,dhNull,hidden);
			var dataList = getArrayCpy(client.data.profileBookmarks["folders"]);
			buildBookmarkFolders(buildTo , dataList);
				dataList = getArrayCpy(client.data.profileBookmarks["files"]);
			buildBookmarkFiles(buildTo , dataList);
			buildTo.setDHParent(dhCont);
			buildTo.show();
	 		client.windows.windshield.setStatus("Idle");
	 		client.windows.windshield.setLoading(false);
		},0);
}

function buildBookmarkFolders(dhCont , dataList){
	var htmlCont = dhCont.obj;
	var currCont = htmlCont;
	var wrkDir = -1;
	var stackA = dataList;
	var stackB = [];
	var currFolders = [];
	var currStack = stackA;
	var nextStack = stackB;
	var postClass = 'postA';
	var margin = 0;

	dhCont.type = 'userBookmark';
	var header = dh.createDHObject("div","hiddenBookHeader","bookmarkFolderInfoRow",htmlCont,dhNull,none);
	buildBookmarkHeader(header);

	while(currStack.length){
		if(currStack == stackA){
			nextStack = stackB;
		}else{
			nextStack = stackA;
		}
		var data = currStack.pop();
		if(data.parent != wrkDir){
			nextStack.push(data);
		}else{
			var row = dh.createDHObject("div",dhCont.id+"_"+data.type+"_"+data.id,'',currCont,dhNull,dhNull);
				row.bookmarkData = data;
				row.margin = (dh.$(row.obj.parentNode.id).type == "userBookmark")? 0 : dh.$(row.obj.parentNode.parentNode.id).margin + 20 ;
				row.listPane = dhCont;
				buildBookmarkFolder( row , data , postClass);
				row.obj.className = "bookmarkFolder";
				currFolders.push({id:data.id,htmlCont:row.obj.childNodes[1]});
				showObject(currCont);
				hideObject(currCont);
		}

		postClass = (postClass == 'postA')? 'postB' : 'postA';
		if(!(currStack.length)){
			if(nextStack.length){
				if(currFolders.length){
					var nextFolder = currFolders.pop();
					currCont = nextFolder.htmlCont;
					wrkDir = nextFolder.id;
				}
				currStack = nextStack;
			}
		}
	}
}
function buildBookmarkFiles(dhCont , dataList){
	var postClass = 'postA';
	for(key in dataList){
		var data = dataList[key];
		var currDHCont = dhCont;
		if(data.parent > 0){
			currDHCont = dh.$(dhCont.id+"_dir_"+data.parent+"_childRow");
		}
		if(!currDHCont){  return false};
		var currCont = currDHCont.obj;

		var row = dh.createDHObject("div",dhCont.id+"_"+data.type+"_"+data.id,'',currCont,dhNull,dhNull);
			row.bookmarkData = data;
			row.margin = (dh.$(row.obj.parentNode.id).type == "userBookmark")? 0 : dh.$(row.obj.parentNode.parentNode.id).margin + 20 ;
			row.listPane = dhCont;

		buildBookmarkFile( row ,data , postClass);
		row.obj.className = "bookmarkFile";
		postClass = (postClass == 'postA')? 'postB' : 'postA';
		currDHCont.showNow();
		currDHCont.hideNow();
	}
}
function buildBookmarkFolder( dhCont , data ,postClass){
	var htmlCont = dhCont.obj;


	var infoRow = dh.createDHObject("div",htmlCont.id+"_infoRow","bookmarkFolderInfoRow p",htmlCont,dhNull,none);
	var childrenRow = dh.createDHObject("div",htmlCont.id+"_childRow","bookmarkChildRow",htmlCont,dhNull,hidden);

	var Description = createObject("div",dhNull,"bookmarkCell",infoRow.obj,dhNull);
	var spacer = createObject("div",dhNull,"fl fv spacer",Description,dhNull);
	var desc = createObject("div",dhNull,"fl fv",Description,dhNull);
	var carot = createObject("div",dhNull,"fl fv treeCarot",desc,dhNull);
	var folderName = createObject("div",dhNull,"fl fv",desc,data["Description"]);

	var DateAdded = createObject("div",dhNull,"bookmarkCell",infoRow.obj,data["Date Added"]);
	var Url = createObject("div",dhNull,"bookmarkCell",infoRow.obj,data["Url"]);

	spacer.style.width = dhCont.margin+"px";

	childrenRow.hideNow();
	infoRow.obj.className += " "+postClass;
	infoRow.obj.onclick=function(){
		if(childrenRow.visible){
			childrenRow.hide();
			//childrenRow.slide(-1);
			carot.style.backgroundImage = "url("+ ecirkitImagesURL +"tree_collapsed.png)";
		}else {
			childrenRow.show();
			//childrenRow.slide(0);
			carot.style.backgroundImage = "url("+ ecirkitImagesURL +"tree_expanded.png)";
		}
	}
/*	childrenRow.slide = function( dy ){
		infoRow.bringToFront();
		if(dy >= 0){childrenRow.show();}
		var height = childrenRow.getH();
		if(dy >= 0){childrenRow.moveTo(dhNull,(-height));}

		dy = (dy < 0)? (dy * height) : 0;
		childrenRow.animate(new dh.tweenDetails( dhNull ,dy,dhNull, dhNull,100, .5, 5),
			function(){
				if(dy < 0){
					childrenRow.hide();
				}else{
					childrenRow.obj.style.top="0px";
				}
			});
	}*/
}
function buildBookmarkHeader(dhCont){
	var htmlCont = dhCont.obj;

	var infoRow = createObject("div",dhNull,"bookmarkFileInfoRow",htmlCont,dhNull);
	var Description = createObject("div",dhNull,"bookmarkCell",infoRow,dhNull);
	var spacer = createObject("div",dhNull,"fl fv spacer",Description,dhNull);
	var desc = createObject("div",dhNull,"fl fv",Description,"Description");

	var DateAdded = createObject("div",dhNull,"bookmarkCell",infoRow,"Date Added");
	var Url = createObject("div",dhNull,"bookmarkCell active",infoRow,"Url");
}
function buildBookmarkFile( dhCont ,data, postClass ){
	var htmlCont = dhCont.obj;
	postClass = "postA";
	if(htmlCont != htmlCont.parentNode.firstChild){
		var last = htmlCont.previousSibling.firstChild;
		if(last.className.replace(/.*(postA).*/,'$1') == "postA"){
			postClass = "postB";
		}
	}
	dhCont.infoRow = createObject("div",dhNull,"bookmarkFileInfoRow",htmlCont,dhNull);
	dhCont.Description = createObject("div",dhNull,"bookmarkCell",dhCont.infoRow,dhNull);
	dhCont.spacer = createObject("div",dhNull,"fl fv spacer",dhCont.Description,dhNull);
	dhCont.desc = createObject("div",dhNull,"fv",dhCont.Description,data["Description"]);

	dhCont.DateAdded = createObject("div",dhNull,"bookmarkCell",dhCont.infoRow,prepDate(data["Date Added"]));
	dhCont.Url = createObject("div",dhNull,"bookmarkCell active",dhCont.infoRow,prepMessage(data["Url"],true,true,false));

	dhCont.Url.onmouseover = function(){
		descriptionPop(data.description);
	}
	dhCont.Url.onmouseout = unregisterToolTip;
	dhCont.Url.onclick = function(){
		loadInBrowser(data);
	};
	dhCont.spacer.style.width = dhCont.margin+"px";
	dhCont.desc.style.marginLeft = dhCont.margin+"px";
	dhCont.Description.style.clear = "left";
	dhCont.infoRow.className += " "+postClass;
}
function initMyNews(){
	
	if(!client.windows.myNews){
		//---------------------------
		//News Pane
		//---------------------------
		client.addWindow( 'myNews',
			{
				startingState:	windowState.minimized,
				resizable:		true,
				closeButton:	false,
				maximizeButton: true,
				minimizeButton: true,
				showTabs:		true,
				showStatus:		true,
				showIcon:		false
			},
			dh.nodes.windowspace.obj,
			"My News"
		);
		dh.nodes.menu_myNews.onClick = function() {
			if( client.windows.myNews.visible ){ client.windows.myNews.minimize(); }
			else { client.windows.myNews.show(); }
		}
		client.windows.myNews.onShow = function (){ updateIcon('myNews'); displayMyNews(); };
		client.windows.myNews.onHide = function (){ updateIcon('myNews'); };
		client.windows.myNews.minimizeTo = dh.nodes.menu_myNews;
		client.windows.myNews.setCanvas( dh.nodes.myNewsCanvas );
	}
	
}

function displayMyNews(){
	if( !client.data.myNews ){
		ajax.post(
			'/processors/user.php',
			{
				type: 'myNews'
			},
			function ( connectionInstance ){
				if( connectionInstance.responseObject )	{
					client.data.myNews = connectionInstance.responseObject;
					displayMyNews();
				}
			},
			function ( connectionInstance ){
				
			},
			client.windows.myNews
		);
	} else {
		
		//display news here
		
	}
}
	
function createMCEInstance(elementId){
	tinyMCE.execCommand( 'mceAddControl', false, elementId);
}

function destroyMCEInstance(elementId) {
	tinyMCE.execCommand( 'mceRemoveControl', false, elementId );
}

function getMCEEditorId(elementId){
	var editorId = tinyMCE.getEditorId(elementId);
	if (!isEmpty(editorId)){
		return editorId;
	}else{
		return false;
	}
}

function getMCEContent(elementId){
	var editorId = getMCEEditorId(elementId);
	var content = tinyMCE.getContent(editorId);
	return content;
}

function setMCEContent(elementId, content){
	setMCEFocus(elementId);
	tinyMCE.setContent(content);
}

function setMCEFocus(elementId){
	var editorId = getMCEEditorId(elementId);
	tinyMCE.execCommand('mceFocus', false, editorId);
}

function insertMCEText(text){
	tinyMCE.execCommand('mceInsertContent', false, text);
}

/*******************************************************
 *
 * 	Remarks -  Show, Resize, Fetch, BuildPane, BuildList, BuildVCR, Pageination
 *
 *
 ******************************************************/
var remarksPerPage = 15;
var currentStart = 0;

function showRemarks(){
	/*
	//did we need to fetch the remarks first?
	if( !fetchWindshieldRemarks() ){
		//fetch's onSuccess Callback will bring us back here
		return;

	//are we supposed to display these remarks?
	//aka. back from fetch
	} else {
	*/
	
	//do we have all the data?
	if( !client.data.profileRemarks && !client.data.contestRemarks ){
		fetchWindshieldRemarks();
		return true;
	}


	if( client.currentLayer == 'comunity' ){
		client.windows.windshield.setLoading(true);
		client.windows.windshield.setStatus("Building Remarks . . .");
	}
	buildRemarksPane(currentStart);
	/*
	}
	*/
}

function resizeRemarksCanvas(){
	this.list.invoke("Show");
}

function fetchWindshieldRemarks(start){
	
	if(!start) var start = 0;
	var end = remarksPerPage;
	currentStart = start;
	
		ajax.post("/api/processors/user",
			{
				type:"userRemarks",
				i:client.getBrowseUserID(),
				s:start,
				e:end
			},
	 		function( conn ){
				
				if(conn && conn.responseObject && conn.responseObject.error){
					switch( conn.responseObject.error ){
						case '6675':
								getObject('userRemarks').innerHTML = '<table height="100%" width="100%"><tbody><tr><td height="100%" width="100%" align="center"><img width="625" height="380" src="/images/perms/windshield.png" /></td></tr></tbody></table>';
								getObject('userRemarks').style.overflow = "visible";
								if(dh.nodes.remarksVCRBottom){
									dh.nodes.remarksVCRBottom.purge();
								}else{
									getObject('remarksVCRBottom').innerHTML = '';
								}
								return false;
							break;
					}
				}else{
					//if we're still browsing the same layer, reload
					//if( conn.requestObject.profileLayer == client.currentLayer ){
					if( conn.requestObject.i == client.getBrowseUserID() ){
						if( client.isContestProfile() ){
							client.data.contestRemarks = conn.responseObject;
						} else {
							client.data.profileRemarks = conn.responseObject;
						}
					}
					getObject('userRemarks').style.overflow = "auto";
		 			setTimeout(function(){ showRemarks() } , 0);
				}
				//}
				//we might have to forace a reload here but no idea
				//setTimeout(function(){fetchWindshieldRemarks(0)},0);				
				
	 			return true;
	 		},
	 		null,
	 		( client.currentLayer == 'community' ) ? client.windows.windshield : null);
	
	return false;
}

function buildRemarksPane(start){
	var dhCont = (( client.isContestProfile() ) ? dh.nodes.mainContent : dh.nodes.remarksCanvas);
	dhCont.purge();

	delete dhCont.list;
	delete dhCont.topVCR;
	delete dhCont.bottomVCR;

	dhCont.list = buildProfileRemarksList(start);
	//dhCont.topVCR = buildVCRMenu('remarksVCRTop',start,"userRemarks");
	dhCont.bottomVCR = buildVCRMenu('remarksVCRBottom',start,"userRemarks");

	//dhCont.topVCR.setDHParent(dhCont);
	dhCont.list.setDHParent(dhCont);
	dhCont.bottomVCR.setDHParent(dhCont);

	//dhCont.topVCR.show();
	dhCont.bottomVCR.show();
	dhCont.list.show();

	if ( client.currentLayer == 'community' ) {
		client.windows.windshield.setStatus("Idle");
		client.windows.windshield.setLoading(false);
	}
}

function buildProfileRemarksList(start){
	if(dh.nodes.userRemarks){
		dh.nodes.userRemarks.obj.parentNode.removeChild(dh.nodes.userRemarks.obj);
		dh.nodes.userRemarks.destroy();
		//delete dh.nodes.userRemarks;
	};
	if(dh.nodes.mainContent){
		dh.nodes.mainContent.purge();
	};	
	

	var data = ( client.isContestProfile() ) ? client.data.contestRemarks["currRemarks"] : client.data.profileRemarks["currRemarks"];
	
	if(!data)data = {};
	
	var	dhCanvas = dh.createDHObject("div","userRemarks","r",canvasStorage,dhNull,none);
		dhCanvas.onShow = function(){fillVertically(this.obj)};
		dh.nodes.userRemarks.remarkDataList = data;
	 	dh.nodes.userRemarks.win = client.windows.windshield;
	var canvas = dhCanvas.obj;

	for(key in data){
		var c = data[key];
		var remark = dh.createDHObject("div",'remark_'+c.remarkId,'profileRemark',canvas,'',none);
		buildRemark('remark_'+c.remarkId,c,"replyRemark","deleteRemark",(key % 2));
	}

	return dhCanvas;
}

function buildVCRMenu( id ,start,listId){
	var remarksData = ( ( client.currentLayer == 'community' ) ? client.data.profileRemarks : client.data.contestRemarks );

	var dhVcr = dh.$(id);
		if(dhVcr){
			dhVcr.obj.parentNode.removeChild(dhVcr.obj);
			dhVcr.purge();
			eval("delete dh.nodes."+id);
		}
	dhVcr = dh.createDHObject("div",id,"profileVCRMenu",canvasStorage,dhNull,hidden);
	var vcr = dhVcr.obj;

	var numPages = Math.ceil((remarksData["totalRemarks"])/remarksPerPage);
	var currPage = (Math.floor((start - 1)/remarksPerPage)) + 1;

	var pagination = ((numPages > 20) ?
						remarkpaginator2000(currPage , numPages,"fetchWindshieldRemarks",remarksPerPage , true) :
						noPaginationHTML(currPage, numPages ));

	var buttonsDiv = createObject('div','','remarksVCRButtons',vcr,pagination);

	if(!(client.isHomeProfile())){
		var optDiv = createObject('div','profileLeaveRemarkButton','leaveRemarkButton active gtl',vcr,'<div style="margin-right:3px;" class="remarkIcon"></div><div class="tanIconText">Add Remark</div>');
			optDiv.onclick = Function("leaveRemark('saveRemark',null,'"+listId+"',client.windows.windshield)");
			client.addHelpBeacon( 'community', optDiv, optDiv.id);
	}
	return dhVcr;
}

function noPaginationHTML( currPage, numPages ,callback){
	var pagination = '';
	if(!callback)
		var callback = 'fetchWindshieldRemarks';
	for(var i = 0 ; i < numPages ; i++){
		if(currPage ==  i) {
			pagination += " <strong class=\"browsePage selected_yellow\">" + (i + 1) + "</strong>";
		} else {
			pagination += " <span class=\"browsePage\" onclick=\""+callback+"('"+((i)*remarksPerPage)+"');\">" + (i + 1) + "</span> ";
		}
	}
	return 	pagination;
}

function remarkpaginator2000( num , resultCount ,callback,perPage , tenPlus){
	var offset = 0;
	var i = 0;
	var pagination = "";
	selectedNum = parseInt(num);

	pagination += "<div class=\"r o f\">";


	if(selectedNum > 9  && !tenPlus){
		pagination += "<div id=\"remarksRewind\" class=\"vcrButton vcrButtonRewind p\" onclick=\""+callback+"('"+((selectedNum - 10)*perPage)+"');\"></div>";
	}
	if(selectedNum > 0){
		pagination += "<div id=\"remarksBack\" class=\"vcrButton vcrButtonBack p\" onclick=\""+callback+"('"+((selectedNum - 1)*perPage)+"');\"></div>";
	}


	pagination += "<div class=\"remarkPageList\">";

	pagination += remarkforLoopinator3000( 0 , 5 , 0 , 0 , -1 ,callback,perPage);
	if(selectedNum > 4 && selectedNum < 8){
		pagination += remarkforLoopinator3000( 5 ,10 , 0 , 0 , 0 ,callback,perPage);
	}
	if((selectedNum > 7) && (selectedNum < resultCount - 9)){
		pagination += "<span class=\"browsePage\">. . .</span>";
		pagination += remarkforLoopinator3000( selectedNum ,selectedNum , 2 , 3 , 0 ,callback,perPage);
	}
	pagination += "<span class=\"browsePage\">. . .</span>";
	if((selectedNum > (resultCount - 10)) && (selectedNum < (resultCount - 4))){
		pagination += remarkforLoopinator3000( resultCount ,resultCount , 10 , -5 , 0 ,callback,perPage);
	}
	pagination += remarkforLoopinator3000( resultCount ,resultCount , 5 , 0 , 0 ,callback,perPage);

	pagination += "</div>";

	if(selectedNum < resultCount - 1){
		pagination += "<div id=\"remarksPlay\" class=\"vcrButton vcrButtonPlay p\" onclick=\""+callback+"('"+((selectedNum + 1)*perPage)+"');\"></div>";
	}
	if(selectedNum < resultCount - 11 && !tenPlus){
		pagination += "<div id=\"remarksForward\" class=\"vcrButton vcrButtonForward p\" onclick=\""+callback+"('"+((selectedNum + 10)*perPage)+"');\"></div>";
	}


	pagination += "</div>";

	return pagination;
};

function remarkforLoopinator3000( start , end , offstart , offend, flag ,callback,perPage){
	var i;
	var pagination = "";

	for(i = (start - offstart); i < (end + offend);i++){
		if(i == selectedNum){
			pagination += "<strong class=\"browsePage selected_yellow\">" + (i+1) + "</strong>";
			if(flag < 0){
				offend = i;
			}
		}else{
			pagination += "<span class=\"browsePage\" onclick=\""+callback+"('"+((i)*perPage)+"');\">"+(i+1)+"</span>";
		}
	}
	return pagination;
};


			function cancelQueue() {
				swfu.cancelQueue();
				document.getElementById(swfu.movieName + "UploadBtn").style.display = "none";
				document.getElementById("cancelqueuebtn").style.display = "none";
			}
			
			function uploadError(errno) {
				// SWFUpload.debug(errno);
			}
	/***************
		Messaging
	***************/
	//window specific data
	var email = null;

	function ecEmail(){ }
	ecEmail.prototype = {

		emailsObj: null, 	// entire list of emails
		fetched: false, 	// boolean value that denotes whether or not emails were fetched
		selectedEmail: null,	// the current email being viewed
		emailBox: null,		// which mailbox the user is viewing inbox or outbox
		composeMailToUser: null, // stores who we're going to be sending an email to
		composeMailMessage: null, // stores our email message
		fckEditor: null, // fck instance
		ar_popAccounts: null, // array of our pop accounts
		crCount: null,
		ccCount: null,
		annCount: null,
		emailCount: null,
		popAccounts: null,
		popBox: null, // currently selected popBox
		popEmails: null, // entire list of pop emails
		selectedPopEmail: null,
		forceReload: false,
		composeFromProfile: false,
		composeFromReply: false,
		replyToUserName: null,
		replyToSubject: null,

		fetchInbox: function ( callback ){
			// if our emails havent been loaded yet, or the emails object does not contain your inbox
			// then fetch our inbox
			if (!email.emailsObj || email.emailBox == 'outbox' || email.forceReload == true){
				ajax.post('/api/processors/messaging',
					{
						type: 'receivedEmail'

					},
					function (connectionInstance) {
						try{
							if (connectionInstance.responseObject){
								var cr = connectionInstance.responseObject;
								email.emailsObj = null;
								email.selectedEmail = null;
								email.emailsObj = cr.emails;
								email.ar_popAccounts = cr.pop_settings;
								email.crCount = cr.cr_count;
								email.ccCount = cr.cc_count;
								email.annCount = cr.ann_count;
								email.emailCount = cr.email_count;
								email.emailBox = 'inbox';
								if(callback)callback();
								email.buildEmailListFilter();
								return true;
							}else{
								email.buildEmailListFilter();
								return false;
							}
						}catch(ex){

						}
						//email.buildEmailListFilter();
					},
					function (connectionInstance) {

					},
					client.windows.myMail
				);
			}else{
				email.emailBox = 'inbox';
				email.showEmailList();
			}
			email.forceReload = false;
		},

		fetchOutbox: function(){

			// if our emails havent been loaded yet, or the emails object does not contain your outbox
			// then fetch our outbox
			if (!email.emailsObj || email.emailBox == 'inbox' || email.forceReload == true){
				ajax.post('/api/processors/messaging',
					{
						type: 'sentEmail'
					},
					function (connectionInstance){
						try{
							if (connectionInstance.responseObject){
								email.emailsObj = null;
								email.selectedEmail = null;
								email.emailsObj = connectionInstance.responseObject;
								email.emailBox = 'outbox';
								email.buildEmailListFilter();
								return true;
							}else{
								return false;
							}
						}catch (ex){

						}
					},
					function (connectionInstance){

					},
					client.windows.myMail
				);
			}else{
				email.emailBox = 'outbox';
				email.showEmailList();
			}
			email.forceReload = false;
		},

		fetchPopBox: function(){

			if (this.popBox <= 0) return false;

			//if (!popEmails || email.emailBox == 'outbox'){
				ajax.post('/api/processors/messaging',
					{
						type: 'fetchPopMail',
						box: this.popBox

					},
					function (connectionInstance) {
						try{
							if (connectionInstance.responseObject){
								email.popEmails  = connectionInstance.responseObject;
								email.buildPopEmailList();
								return true;
							}else{
								return false;
							}
						}catch (ex){

						}
					},
					function (connectionInstance) {

					},
					client.windows.myMail
				);
		//	}else{
		//		email.emailBox = 'inbox';
		//		email.showEmailList();
		//	}


		},

		buildEmailListFilter: function (){

			// the html area where the list is the be displayed
			var email_list = getObject('inbox_list');
			email_list.innerHTML = '';

			// build our filter select box
			var annCt = !isEmpty(email.annCount)? email.annCount : 0;
			var ccCt = !isEmpty(email.ccCount)? email.ccCount : 0;
			var crCt = !isEmpty(email.crCount)? email.crCount : 0;
			var eCt = !isEmpty(email.emailCount)? email.emailCount : 0;

			var select;
			select = '<select id="myEmailFilterSelect" name="myEmailFilterSelect" onchange="email.boxSwitcher();">';
				select += '<option value="-1" class="listHeading" disabled="true">eCirkit Mailboxes</option>';
				select += '<option value="ib">Inbox</option>';
				if (email.emailBox == 'inbox'){
					select += '<option value="an">&nbsp;-- Announcements (' + annCt + ')</option>';
					select += '<option value="cc">&nbsp;-- Cirkit Connects (' + ccCt + ')</option>';
					select += '<option value="cr">&nbsp;-- Contact Requests (' + crCt + ')</option>';
					select += '<option value="em">&nbsp;-- eCirkit E-mails (' + eCt + ')</option>';
					select += '<option value="ob">Outbox</option>';
					if (email.ar_popAccounts){
						select += '<option value="-1" class="listHeading" disabled="true">POP/IMAP Mailboxes</option>';
						for (var i = 0; i < email.ar_popAccounts.length; i ++){
							select += '<option value="pop_' + email.ar_popAccounts[i].pop_id + '">' + email.ar_popAccounts[i].name + '</option>';
						}
					}
				}else{
					select += '<option value="ob" selected>Outbox</option>';
				}

			select += '</select>';

			var filter = getObject('inbox_controls');
			filter.innerHTML = '<div id="myEmailInboxFilter" class="myEmailInboxFilter gtm">Mailbox: ' + select + '</div>';

			// build the list
			this.buildEmailList(getObject('myEmailFilterSelect').value);
		},

		boxSwitcher: function(box){
			dh.nodes.inbox_content.purge();
			var box = getObject('myEmailFilterSelect').value;

			if (box.substring(0, 4) == "pop_"){
				var tmp = box.split("_");
				var popBox = tmp[1];
				if (popBox > 0){
					this.popBox = popBox;
					this.fetchPopBox();
				}
			}else{
				this.buildEmailList(box);
			}
		},

		buildEmailList: function(box){
			// clear our list
			var email_list = getObject('inbox_list');
			email_list.innerHTML = '';

			var content = ''; 	/* HTML Content 			*/
			var e = ''; 		/* Individaul email object 	*/
			var cls = ''; 		/* CSS Class 				*/
			var subject = ''; 	/* Message Subject 			*/

			// if box was not passed in, grab it from the select box
			if (isEmpty(box)){
				box = getObject('myEmailFilterSelect').value;
			}

			// are we forcing a reload?
			if (this.forceReload == true){
				if (box == 'ob'){
					this.fetchOutbox();
					return true;
				}else{
					this.fetchInbox();
					return true;
				}
			}

			// are we switching between boxes?
			// if the user requested the outbox or inbox, fetch the emails
			// otherwise, just filter the current list
			if (box == 'ob' && this.emailBox == 'inbox'){
				this.fetchOutbox();
				return true;
			}else if (box == 'ib' && this.emailBox == 'outbox'){
				this.fetchInbox();
				return true;
			}

			if(email.emailsObj && email.emailsObj.length)
			for (var i = 0; i < email.emailsObj.length; i++){

				e = email.emailsObj[i];

				if (!e) continue;
				// only apply these rules if we're in the inbox
				if (email.emailBox == 'inbox'){
					if (box == 'cc'){
						if (!e.cirkitConnectId){
							continue;
						}
					}else if (box == 'an'){
						if (!e.announcementId){
							continue;
						}
					}else if (box == 'cr'){
						if (!e.contactRequestId){
							continue;
						}
					}else if (box == 'em'){
						if (!e.emailId){
							continue;
						}
					}
				}

				// deteremine the type
				if (e.cirkitConnectId){
					//subject = isEmpty(e.subject)? 'Cirkit Connect' : e.subject;
					subject = 'Cirkit Connect';
					cls = 'systemMessage cirkitConnect';
					if (e.toUserId1 == client.loggedInID  && this.emailBox == 'inbox'){
						if (e.toUser1DateViewed == '0000-00-00 00:00:00'){
							cls += ' unRead';
						}
					}else if (e.toUserId2 == client.loggedInID  && this.emailBox == 'inbox'){
						if (e.toUser2DateViewed == '0000-00-00 00:00:00'){
							cls += ' unRead';
						}
					}
				}else if (e.contactRequestId){
					//subject = isEmpty(e.subject)? 'Contact Request' : e.subject;
					subject = 'Contact Request';
					cls = 'systemMessage contactRequest';
					if (e.toUserDateViewed == '0000-00-00 00:00:00' && this.emailBox == 'inbox'){
						cls += ' unRead';
					}
				}else if (e.emailId){
					subject = isEmpty(e.subject)? '(no subject)' : e.subject;
					if (e.dateViewed == '0000-00-00 00:00:00' && this.emailBox == 'inbox'){
						cls = 'unRead';
					}else{
						cls = '';
					}
				}else if (e.announcementId){
					//subject =  isEmpty(e.subject)? 'Announcement' : e.subject;
					subject = 'Announcement';
					cls = 'systemMessage announcement';
					if (e.viewed == 0  && this.emailBox == 'inbox'){
						cls += ' unRead';
					}
				}

				var userDisplayName = '';
				if (isEmpty(e.cirkitConnectId) && e.userDisplayName){
					userDisplayName = ' - ' + e.userDisplayName.substring(0,10);
				}

				subject += '<span class="gtxs ttn overflowh emailFromUser">' + userDisplayName + '</span>';

				content += 	'<div id="email_' + email.emailBox + "_" + i + '" class="p emailSubjectWrapper ' + cls + '"  onclick="email.getEmailContent('+ i +'); ">' +
								'<div id="emailSubject_' + email.emailBox + "_" + i + '" class="emailSubject">' + subject + '</div>' +
								'<div id="emailDate_' + email.emailBox + "_" + i + '" class="emailDate">' +
									formatDateTime(e.dateCreated) +
								'</div>' +
							'</div>';

			}

			email_list.innerHTML = content;
			email.fetched = true;

		},

		buildPopEmailList: function(){

			var email_list = getObject('inbox_list');
			email_list.innerHTML = '';
			var content = '';

			var from = '';
			var subject = '';
			var date = '';

			if(email.popEmails && email.popEmails.length)
			for (var i = 0; i < email.popEmails.length; i++){
				var p = email.popEmails[i];
				subject = p.subject;
				date = p.date;
				content += 	'<div id="pop_' + i + '" class="p emailSubjectWrapper"  onclick="email.showPopEmailContent(' + i + ');">' +
									'<div id="popSubject_' + i + '" class="emailSubject">' + subject + '</div>' +
									'<div id="popDate_' + i + '" class="emailDate">' +
										formatDateTime(date) +
									'</div>' +
								'</div>';

			}
			email_list.innerHTML = content;

		},

		setSelected: function(index){
			if (email.selectedEmail != null){
				var selected = getObject("email_" + email.emailBox + "_" + email.selectedEmail);
				if (selected){
					var tmpClass = selected.className;
					tmpClass = tmpClass.replace("selected", "");
					selected.className = tmpClass;
				}
			}
			if(index < 0) index = 0;
			var e = getObject("email_" + email.emailBox + "_" + index);
			if(!e)return;
			e.className += ' selected ';
			email.selectedEmail = index;
		},

		showPopEmailContent: function(index){
			email.setPopSelected(index);
			var content = getObject('inbox_content');
			var e = email.popEmails[index];
			var controls = '<a class="p actionLabel" onclick="email.deletePopMessage(' + index + ');">DELETE</a>';
			var data = '';

			data += '<div id="" class="popEmailTopWrapper">' +
						'<div id="" class="popEmailContentTitle">' + e.subject +
							'<span class="popMailInfo popMailFrom"><strong>From:</strong> ' + e.fromAddress + '</span>' +
							'<span class="popMailInfo popMailDate"><strong>Date:</strong> ' + prepDate(e.date) + '</span>' +
							'<span class="popMailInfo popMailTo"><strong>To:</strong> ' + e.toAddress + '</span>' +
						'</div>' +
						'<div id="" class="emailControls">' + controls + '</div>' +
					'</div>' +
					'<div id="" class="emailContentWrapper">' +
						'<div id="" class="popEmailContent"><pre>' + e.body + '</pre></div>' +
					'</div>';

			content.innerHTML = data;

		},

		getEmailContent: function (index){

			var e = email.emailsObj[index];

			if (!isEmpty(e.message)){
				this.showEmailContent(index);
				return;
			}

			var id = '';
			var msg = '';

			if (e.cirkitConnectId){
				id = e.cirkitConnectId;
				msg = "cc";
			}else if (e.contactRequestId){
				id = e.contactRequestId;
				msg = "cr";
			}else if (e.emailId){
				id = e.emailId;
				msg = "em";
			}else if (e.announcementId){
				id = e.announcementId;
				msg = "ann";
			}

			ajax.post('/api/processors/messaging',
				{
					type: 'getEmailContent',
					msg: msg,
					id: id
				},
				function (connectionInstance) {
					if (connectionInstance.responseObject){
						email.emailsObj[index] = connectionInstance.responseObject;
						email.showEmailContent(index);
					}
				},
				function (connectionInstance) {

				},
				client.windows.myMail,false
			);

		},

		showEmailContent: function(index){

			email.setSelected(index);
			email.markAsRead(index);

			var content = getObject('inbox_content');

			var e = email.emailsObj[index];
			if (isEmpty(e.message)){
				this.getEmailContent(index);
				return;
			}


			var deleteString =  '<div class="actionIconWrapper" onclick="email.deleteMessage(' + index + ');">' +
									'<div class="actionIcon icon24 xCircleTan24"></div>'+
									'<div class="actionIconText">DELETE</div>' +
								'</div>';

			var replyString = '<div class="actionIconWrapper" onclick="email.composeReplyEmail(' + index + ');">' +
									'<div class="actionIcon icon24 reloadCircleTan24"></div>'+
									'<div class="actionIconText">REPLY</div>' +
							  '</div>';

			// only show these controls if we're in the inbox
			if (email.emailBox == 'inbox'){
				if (e.cirkitConnectId){
					// cirkit connect
					var controls = deleteString;
					controls += '<div class="actionIconWrapper" onclick="email.acceptCirkitConnect(' + index + ');">' +
									'<div class="actionIcon tanCheckCircleIcon"></div>'+
									'<div class="actionIconText">ACCEPT</div>' +
								'</div>';

				}else if(e.contactRequestId){
					// contact request
					var controls = '<div class="actionIconWrapper" onclick="email.ignoreContactRequest(' + index + ');">' +
										'<div class="actionIcon tanMinusCircleIcon"></div>'+
										'<div class="actionIconText">IGNORE</div>' +
									'</div>';

						controls += '<div class="actionIconWrapper" onclick="email.acceptContactRequest(' + index + ');">' +
										'<div class="actionIcon tanCheckCircleIcon"></div>'+
										'<div class="actionIconText">ACCEPT</div>' +
									'</div>';
				}else if (e.emailId){
					// email
					var controls = deleteString + replyString;
				}else if (e.announcementId){
					// announcements
					var controls = deleteString + replyString;
				}else{
					client.userError('E-mail', 'Request failed. Please try again.');
				}
			}else if (email.emailBox == 'outbox'){
				var controls = deleteString;
			}

			var data = '';

			// determine the user id whose avatar we're going to display
			var userId = '';
			var displayAvatar = true;
			if (e.cirkitConnectId ){
				// if this is a cirkit connect
				// we have to display the right avatar
				if (e.toUserId1 == client.loggedInID){
					userId = e.toUserId2;
				}else if (e.toUserId2 == client.loggedInID){
					userId = e.toUserId1;
				}
				if (email.emailBox == 'outbox'){
					displayAvatar = false;
				}
			}else if (e.contactRequestId){
				userId = e.avatarUserId;
				if (email.emailBox == 'outbox'){
					displayAvatar = false;
				}
			}else if (e.announcementId){
				userId = e.fromUserId;
				if (email.emailBox == 'outbox') 	displayAvatar = false;
			}else{
				if (email.emailBox == 'inbox'){
					userId = e.fromUserId;
				}else if (email.emailBox == 'outbox'){
					userId = e.toUserId;
				}
			}

			var subject = e.subject;
			if (displayAvatar == true){
				var userDisplayName = e.userDisplayName;
				var userSex = isEmpty(e.userSex)? '' : e.userSex;
				var age = isEmpty(e.age)? '' : e.age;
				var location = isEmpty(e.location)? '' : e.location;
				var dateJoined = e.dateJoined.substring(0, 10);
				var lastLogin = e.lastLogin.substring(0, 10);
				var interests = !isEmpty(e.interests)? e.interests.substring(0, 90) + '...' : 'n/a';
			}


			data += '<div id="" class="emailTopWrapper">' +
						'<div id="" class="emailContentTitle">' + subject + '<span class="gtxs">&nbsp;&nbsp;' + prepDate(e.dateCreated) + '</span></div>' +
						'<div id="" class="emailControls">' + controls + '</div>' +
					'</div>' +
					'<div id="" class="emailContentWrapper">';
					if (displayAvatar == true){
						data +=	'<div id="emailUserDetails_' + index + '" class="emailUserDetailsWrapper">' +
									'<span class="emailUserOnline"></span>' +
									((parseInt(e.online) == 1)?  '<span class="avatarOnlineNow"></span>' : '') +
									'<span class="emailUserName">' + userDisplayName + '</span>' +
									'<span class="emailAvatar"><img src="/api/servlets/images?user_id=' + userId + '&type=avatar&width=85&height=85" onclick="client.browseUser(' + userId + ');  return false;" style="cursor: pointer;"></span>' +
									'<span class="emailUserDetail"><span class="b di">Sex/Age: </span><span class="di">' + userSex + '/' + age + '</span></span>' +
									'<span class="emailUserDetail"><span class="b di">Location: </span><span class="di">' + location  + '</span></span>' +
									'<span class="emailUserDetail"><span class="b di">Joined: </span><span class="di">' + dateJoined + '</span></span>' +
									'<span class="emailUserDetail"><span class="b di">Last Login: </span><span class="di">' + lastLogin + '</span></span>' +
									'<span class="emailUserDetail emailUserDetailInterests"><span class="b di">Interests: </span><span class="di">' + interests + '</span></span>' +
								'</div>';
					}
					data +=	'<div id="" class="emailContent" ' + ((displayAvatar == false)? 'style="left: 2px;"' : "") + '>' + e.message + '</div>' +
					'</div>';

			content.innerHTML = data;
		},

		markAsRead: function (index){

			if (email.emailBox != 'inbox') return false;

			var e = email.emailsObj[index];

			// return false if this mail was already viewed
			if (e.announcementId && e.viewed == 1){
				return false;
			}else if (e.emailId && e.dateViewed != '0000-00-00 00:00:00'){
				return false;
			}else if (e.contactRequestId && e.toUserDateViewed != '0000-00-00 00:00:00'){
				return false;
			}else if (e.cirkitConnectId){
				if (e.toUserId1 == client.loggedInID){
					if (e.toUser1DateViewed != '0000-00-00 00:00:00'){
						return false;
					}
				}else if (e.toUserId2 == client.loggedInID){
					if (e.toUser2DateViewed != '0000-00-00 00:00:00'){
						return false;
					}
				}
			}

			var unread = getObject("email_" + email.emailBox + "_" + index);
			if (unread){
				var tmpClass = unread.className;
				tmpClass = tmpClass.replace("unRead", "");
				unread.className = tmpClass;
			}

			var id = '';
			var msg = '';
			if (e.announcementId){
				id = e.announcementId;
				msg = 'ann';
			}else if (e.emailId){
				id = e.emailId;
				msg = 'em';
			}else if (e.contactRequestId){
				id = e.contactRequestId;
				msg = 'cr';
			}else if (e.cirkitConnectId){
				id = e.cirkitConnectId;
				msg = 'cc';
			}else{
				return false;
			}

			ajax.post('/api/processors/messaging',	{type: 'markAsRead',id: id, msg: msg},	function (connectionInstance) {	},	function (connectionInstance) {	}	);

		},

		ignoreContactRequest: function(index){

			var cr = email.emailsObj[index];

			ajax.post('/api/processors/messaging',
				{
					type: 'ignoreContactRequest',
					id: cr.contactRequestId
				},

				function (connectionInstance) {
					if (connectionInstance.serverResponse == 'false'){
						client.userError('Contact Request', 'Could not ignore contact request. Please try again');
					}else if (connectionInstance.responseObject.Error){
						client.userError('Contact Request', connectionInstance.responseObject.Error);
					}else if (connectionInstance.serverResponse == 'ok'){
						email.removeMessage(index);
					}
					return true;
				},

				function (connectionInstance) {
					client.userError('E-mail', 'Request failed. Please try again.');
				}

			);
		},

		acceptCirkitConnect: function(index){

			var e = email.emailsObj[index];

			ajax.post('/api/processors/messaging',
				{
					type: 'acceptCirkitConnect',
					id: e.cirkitConnectId
				},

				function (connectionInstance){
					if (connectionInstance.serverResponse == 'true'){
						client.userNotice('Cirkit Connect', 'Cirkit connect accepted.');
						email.removeMessage(index);
					}else{
						client.userError('Cirkit Connect', 'Could not accept cirkit connect. Please try again.');
					}
					return true;
				},

				function (connectionInstance){
					client.userError('E-mail', 'Request failed. Please try again.');
				}
			);
		},

		acceptContactRequest: function(index){

			var e = email.emailsObj[index];

			ajax.post('/api/processors/messaging',
				{
					type: 'acceptContactRequest',
					id: e.contactRequestId
				},

				function (connectionInstance){
					if (connectionInstance.serverResponse == 'ok'){
						delete client.data.profileContacts;
						setTimeout(function(){ displayProfileContacts(); }, 0);
						client.userNotice('Contact Request', 'Contact request accepted.');
						email.removeMessage(index);

					}else{
						client.userError('Contact Request', 'Could not accept contact request. Please try again.');
					}
					return true;
				},

				function (connectionInstance){
					client.userError('E-mail', 'Request failed. Please try again.');
				}

			);

		},

		getPopList: function (){

			ajax.post('/api/processors/messaging',
				{
					type: 'getPopAccounts'
				},

				function (connectionInstance){
					if (connectionInstance.responseObject){
						email.popAccounts = connectionInstance.responseObject;
					}
					dh.nodes.pop_content.purge();
					email.buildPopList();
				},

				function (connectionInstance){
					client.userError('E-mail', 'Request failed. Please try again.');
				},
				client.windows.myMail

			);

		},

		buildPopList: function(){

			if (!email.popAccounts) return false;
			var content = '';
			content += 	'<div id="addNewPopAccountWrapper" class="gtm">' +
							'<span class="addNewPopAccountLinkImage" onclick="email.showPopAccountDetails();"></span>' +
							'<span class="addNewPopAccountLink"><a onclick="email.showPopAccountDetails();">Add new pop account</a></span>' +
						'</div>';


			if (email.popAccounts){
				for (var i = 0; i < email.popAccounts.length; i ++){
					p = email.popAccounts[i];
					content += '<div " class="p emailSubjectWrapper"  onclick="email.showPopAccountDetails(' + i + ');">' +
								 '<div id="" class="emailSubject">' + ((isEmpty(p.name))? p.user_name : p.name) + '</div>' +
	   						    '</div>';
				}
			}

			var list = getObject('pop_list');
			list.innerHTML = content;

		},

		showPopAccountDetails: function(index){

			var name = '';
			var user_name = '';
			var server = '';
			var port = '110';
			var pass = '';
			var ssl = 0;
			var tls = 0;

			if (index >= 0){
				var p = email.popAccounts[index];
				name = p.name;
				user_name = p.user_name;
				server = p.server;
				port = p.port;
				pass = p.password;
				ssl = p.ssl;
				tls = p.tls;
			}

			var content = '';
			content += '<table border="0" cellpadding="0" cellspacing="4" width="100%">';
				content += '<tr>';
					content += '<td class="gts" align="right" valign="top">Name: </td>';
					content += '<td><input type="text" name="popMailboxName" id="popMailboxName" size="30" value="' + name + '"></td>';
				content += '</tr>';
				content += '<tr>';
					content += '<td class="gts" align="right" valign="top">Email Address: </td>';
					content += '<td><input type="text" name="popEmailAddress" id="popEmailAddress" size="30" value="' + user_name + '"></td>';
				content += '</tr>';
				content += '<tr>';
					content += '<td class="gts" align="right" valign="top">Password: </td>';
					content += '<td><input type="password" name="popPassword" id="popPassword" size="30" value="' + pass + '"></td>';
				content += '</tr>';
				content += '<tr>';
					content += '<td class="gts" align="right" valign="top">POP Server: </td>';
					content += '<td><input type="text" name="popServer" id="popServer" value="' + server + '" size="30">&nbsp;&nbsp;&nbsp;' +
									'<span class="gtm">Port: </span><input type="text" name="popServerPort" id="popServerPort" size="5" maxlength="10" value="' + port + '"></td>';
				content += '</tr>';
				content += '<tr>';
					content += '<td class="gts" align="right" valign="top">Security: </td>';
					content += '<td class="gts"><input type="radio" name="popSecurity" id="popSecurity" value="none" checked> None&nbsp;&nbsp;&nbsp;' +
									'<input type="radio" name="popSecurity" id="popSecurity" value="tls" ' + ((tls == 1 && ssl == 0)? 'checked' : '') + '> TLS&nbsp;&nbsp;&nbsp;' +
									'<input type="radio" name="popSecurity" id="popSecurity" value="ssl" ' + ((ssl == 1 && tls == 0)? 'checked' : '') + '> SSL';
					content += '</td>';
				content += '</tr>';
				content += '<tr>';
					content += '<td>&nbsp;</td>';
					content += '<td><input type="button" value="Test Settings" id="popAccountTest" name="popAccountTest" onclick="email.testPopAccount();">&nbsp;&nbsp;' +
									'<input type="button" value="Save" id="popAccountSave" name="popAccountSave" onclick="email.savePopAccount(' + index + ');">&nbsp;&nbsp;' +
									'<input type="button" value="Cancel" id="popAccountCancel" name="popAccountCancel" onclick="dh.nodes.pop_content.purge();">';

					if(index >= 0){
						content += '&nbsp;&nbsp;<input type="button" value="Delete" id="popAccountDelete" name="popAccountCancel" onclick="email.deletePopAccount(' + index + ');">';
					}
					content += '</td>';
				content += '</tr>';
			content += '</table>';
			content += '<div id="popAccountStatus" class="gts" style="display: none;"></div>';

			var container = getObject('pop_content');
			container.innerHTML = content;
		},

		deletePopAccount: function (index){

			var p = this.popAccounts[index];
			if (!p) return false;

			ajax.post('/api/processors/messaging',
				{
					type: 'deletePopAccount',
					pid: p.pop_id
				},

				function (connectionInstance){
					if (connectionInstance.serverResponse == 'ok'){
						email.getPopList();
					}else{
						client.userError('E-mail', 'Could not delete pop account. Please try again.');
					}
				},

				function (connectionInstance){

				},client.windows.myMail,false
			);

		},

		testPopAccount: function(){
			var popemail = getObject('popEmailAddress').value;
			if (isEmpty(popemail)){
				client.userNotice('E-mail', 'Please enter your email address.');
				return false;
			}
			var server = getObject('popServer').value;
			if (isEmpty(server)){
				client.userNotice('E-mail', 'Please enter the POP server for this email account.');
				return false;
			}
			var password = getObject('popPassword').value;
			if (isEmpty(password)){
				client.userNotice('E-mail', 'Please enter the password for this account.');
				return false;
			}

			var port = getObject('popServerPort').value;
			if (isEmpty(port)){
				port = 110;
			}

			var security = radioValue('popSecurity');
			if (isEmpty(security)){
				security = 'none';
			}

			var status = getObject('popAccountStatus');
			status.style.display = 'block';
			status.innerHTML = 'Testing account settings...';

			ajax.post('/api/processors/messaging',
				{
					type: 'testPopAccount',
					email: popemail,
					server: server,
					port: port,
					pass: password,
					security: security
				},

				function (connectionInstance){
					if (connectionInstance.responseObject){
						status.innerHTML = 'Connected successfully to ' + server + '.';
						status.innerHTML += '<br />&nbsp;&nbsp;&nbsp;Total messages: ' + connectionInstance.responseObject.messages + '.';
						status.innerHTML += '<br />&nbsp;&nbsp;&nbsp;Total new messages: ' + connectionInstance.responseObject.new_messages + '.';
					}else{
						status.innerHTML = '<font style="color: red">Could not connect to ' + server + '. Please check your settings and try again.</font>';
					}

				},

				function (connectionInstance){

				},client.windows.myMail,false
			);

		},

		savePopAccount: function(index){

			var pid = '';
			if (index >= 0){
				pid = this.popAccounts[index].pop_id;
			}

			var popemail = getObject('popEmailAddress').value;
			if (isEmpty(popemail)){
				client.userNotice('E-mail', 'Please enter your email address.');
				return false;
			}
			var server = getObject('popServer').value;
			if (isEmpty(server)){
				client.userNotice('E-mail', 'Please enter the POP server for this email account.');
				return false;
			}
			var password = getObject('popPassword').value;
			if (isEmpty(password)){
				client.userNotice('E-mail', 'Please enter the password for this account.');
				return false;
			}

			var port = getObject('popServerPort').value;
			if (isEmpty(port)){
				port = 110;
			}

			var security = radioValue('popSecurity');
			if (isEmpty(security)){
				security = 'none';
			}

			var name = getObject('popMailboxName').value;
			if (isEmpty(name)){
				name = email;
			}

			client.userNotice('E-mail', 'We will attempt to download all your messages for ' + popemail + '. This may take a few minutes depending on the size of your mailbox.');

			ajax.post('/api/processors/messaging',
				{
					type: 'savePopAccount',
					email: popemail,
					server: server,
					port: port,
					pass: password,
					security: security,
					pid: pid,
					name: name
				},

				function (connectionInstance){
					if (connectionInstance.serverResponse == 'false'){
						client.userError('E-mail', 'We were unable to connect to your account at ' + server + '. Please double check the information you provided and try again.');
					}else if (connectionInstance.serverResponse == 'ok'){
						client.userNotice('E-mail', 'All of your emails for ' + popemail + ' have been successfully downloaded. You may now view these message in your Inbox.');
					}
					email.emailsObj = null;
					email.getPopList();
				},

				function (connectionInstance){

				},client.windows.myMail
			);
		},

		composeEmail: function(index, reply){

			if (!email.composeFromReply){
				email.composeMailMessage = '';
			}

			// check to see if we have an editor instance
			// if we do, destroy it
			try{
				var editorId = getMCEEditorId('composeMailMessage');
				if (editorId){
					destroyMCEInstance('composeMailMessage');
				}
			}catch(err){}

			var userDisplayName = '';

			if (email.composeFromReply){
				userDisplayName = email.replyToUserName;
			}else if (email.composeFromProfile){
				userDisplayName = client.data.viewUserInfo.profile_info.display_name;
			}

			var subject = '';
			if (email.composeFromReply){
				subject = email.replyToSubject;
			}

			var composeCanvas = getObject('composeCanvas');
			composeCanvas.innerHTML = '';
			var content = '';
			content =	'<div class="a o f overflowh">'+
							'<div class="a o fh" style="background:url(/images/themes/launch/compose_mail.png) repeat;height:50px"></div>'+
							'<div class="a o" style="background:#c9deec;top:50px;width:200px;height:1000px;"></div>'+
						'</div>'+
						'<table width="100%" cellpadding="5" border="0" class="r">' +
						  '<tr height="25">' +
						    '<td width="15%" valign="middle" align="right" class="composeMailLeftColumn tanIconText"  style="line-height:25px;">To:</td>' +
						    '<td width="85%" valign="top"><div id="toWrapper" class="inputBoxWrapper" style="position: absolute;">' +
						    	'<span id="composeMailSearchIcon" class="composeMailSearchIcon" onmousedown="email.toggleSendToList();"></span>' +
						    	'<input type="text" name="toUser" id="composeMailToUser" onfocus="email.buildSendToList();" onkeyup="email.buildSendToList();" value="' + userDisplayName + '" style="background:url(/images/inputbg.png);" />' +
						    	'&nbsp;<input type="checkbox" name="composeAnnouncement" id="composeAnnouncement" value="false" onclick="email.toggleAnnouncement();"> Announcement' +
						    '</div></td>' +
						  '</tr>' +
						  '<tr height="25">' +
						  	//'<td>'+
								//'<table width="100%" cellpadding="5" border="0">' +
									// '<tr height="25">' +
									    '<td align="right" valign="middle" class="composeMailLeftColumn tanIconText"  style="line-height:25px;">Subject:</td>' +
									    '<td valign="top"><div id="subjectWrapper" class="inputBoxWrapper"><input type="text" size="60" maxlength="64" name="subject" value="' + subject + '" id="composeMailSubject" style="background:url(/images/inputbg.png);" /></div></td>' +
									//'</tr>'+
								//'</table>'+
							//'</td>' +

						  '</tr>' +
						  '<tr>' +
						    '<td align="right" valign="top" class="composeMailLeftColumn tanIconText"  style="line-height:25px;">Message:</td>' +
						    '<td valign="top" id="composeMailMessageEditableArea">' +
						      '<textarea id="composeMailMessage" name="composeMailMessage" style="width: 98%;" rows="15">' + email.composeMailMessage + '</textarea>' +
						    '</td>' +
						  '</tr>' +
						 // '<tr>' +
						 // 	'<td>&nbsp;</td>' +
						 // 	'<td><a class="actionLabel" onclick="email.sendEmail();">SEND</a>&nbsp;&nbsp;&nbsp;<a class="actionLabel" onclick="client.windows.myMail.__tab(\'inbox\');">CANCEL</a></td>' +
						 // '</tr>' +
						'</table>'+
						'<div class="composeMailControls a">'+
								'<div class="actionIconWrapper"  onclick="client.windows.myMail.__tab(\'inbox\');">'+
									'<div class="actionIcon icon24 xSquareTan24"></div>'+
									'<div class="actionIconText">CANCEL</div>'+
								'</div>'+
								'<div class="actionIconWrapper" onclick="email.sendEmail();">'+
									'<div class="actionIcon icon24 checkSquareTan24"></div>'+
									'<div class="actionIconText">SEND</div>'+
								'</div>'+
							'</div>';


			composeCanvas.innerHTML = content;

			// create our editor
			createMCEInstance('composeMailMessage');
			//var t = getObject('composeMailMessage');
			//t.value = email.composeMailMessage;
			//alert(t.value);

			email.composeFromProfile = false;
			email.composeFromReply = false;
			email.replyToUserName = '';

		},

		toggleSendToList: function (){
			//if (getObject('composeMailFriendList')){
			if (dh.nodes.composeMailFriendList){
				dh.nodes.composeMailFriendList.destroy();
			}else{
				this.buildSendToList();
			}
			//}
		},

		composeReplyEmail: function (index){

			email.composeFromReply = true;
			var e = email.emailsObj[index];
			email.composeMailMessage = '<br /><br /><br /><br /><br /><br /><hr />----- Original Message -----<br />';
			email.composeMailMessage += 'From: ' + e.userDisplayName + '<br />';
			email.composeMailMessage += 'Sent: ' + e.dateCreated + '<br />';
			email.composeMailMessage += 'Subject: ' + e.subject + '<br />';
			email.composeMailMessage += '<br />' + e.message;
			email.composeMailToUser = e.fromUserId;
			email.replyToSubject = 'Re: ' + e.subject;
			email.replyToUserName = e.userDisplayName;
			client.windows.myMail.__tab('compose');

		},

		composeProfileEmail: function (){

			email.composeFromProfile = true;
			email.composeMailToUser = client.data.viewUserInfo.profile_info.user_id;
			client.windows.myMail.__tab('compose');

		},

		toggleAnnouncement: function(){

			var checkbox = getObject('composeAnnouncement');
			var toUserTxt = getObject('composeMailToUser');
			var icon = getObject('composeMailSearchIcon');

			if (checkbox.checked){
				toUserTxt.disabled = true;
				icon.style.visibility = 'hidden';
				toUserTxt.style.background = '#D6D5D9';
			}else{
				toUserTxt.disabled = false;
				icon.style.visibility = 'visible';
				toUserTxt.style.background = '#FFFFFF';
			}

		},

		buildSendToList: function(){

			var toWrapper = getObject('toWrapper');

			var searchString = getObject('composeMailToUser').value;

			//if (searchString.length >= 1){
				ajax.post('/api/processors/friends',
					{
						type: 'search',
						s: searchString
					},

					function (connectionInstance){

						var friends = connectionInstance.responseObject;

						if (!getObject('composeMailFriendList')){
							var friendList = createObject('div', 'composeMailFriendList', 'composeMailFriendList', toWrapper);
							//createObject(tag, id, classname, parent, innerHTML, type)
						}else{
							var friendList = getObject('composeMailFriendList');
						}

						var txtBox = getObject('composeMailToUser');
						var txtW = getW(txtBox);
						var txtH = getH(txtBox);
						var txtTop = getX(txtBox);
						var txtLeft = getY(txtBox);
						friendList.style.position = 'absolute';
						friendList.style.top = txtTop+txtH;
						friendList.style.left = txtLeft;

						dh.addObject(friendList.id);

						friendList.innerHTML = '';
						var list = '';

						var img = '';

						for (var i = 0; i < friends.length; i++){
							//img = "/api/servlets/images?photo_id=" + friends[i].photoId + "&format=png&size=25";
							//<div class="friendListAvatar"><img src="' + img + '"></div>
							list += '<div class="friendListItem" id="friendListItem' + i + '" onmousedown="email.setComposeToUser(\'' + friends[i].userName + '\', \'' + friends[i].user_id + '\'); return false;">' + friends[i].userName + '</div>';
						}

						friendList.innerHTML = list;

						return true;
					},

					function (connectionInstance){

					}

				);
			//}

		},

		setComposeToUser: function(displayName, userId){

			var toUserTextBox = getObject('composeMailToUser');
			toUserTextBox.value = displayName;

			email.composeMailToUser = userId;

			// better to destroy it, because this list wont be used often
			dh.nodes.composeMailFriendList.destroy();
		},

		sendEmail: function (){

			var annCheckbox = getObject('composeAnnouncement');

			if (isObject(annCheckbox) && !annCheckbox.checked){
				if (email.composeMailToUser <= 0){
					client.userError('E-mail', 'Please select a user to send this email to.');
					return false;
				}
			}

			var subject = getObject('composeMailSubject').value;
			if (subject.length <= 0){
				subject = "(no subject)";
			}

			//tinyMCE.triggerSave();
			tinyMCE.triggerSave(true, true);
			var message = getMCEContent('composeMailMessage');
			if (message.length <= 1){
				client.userNotice('E-mail', 'Please enter a message.');
				return false;
			}

			// is this an announcement?
			if (isObject(annCheckbox) && annCheckbox.checked){

				client.userNotice('ANNOUNCEMENTS', 'Announcement sent successfully.');

				client.windows.myMail.__tab('inbox');

				ajax.post('/api/processors/messaging',
					{
						type: 'sendAnnouncement',
						subject: subject,
						message: message
					},

					function (connectionInstance){
						if (connectionInstance.serverResponse == 'ok'){
							email.composeMailToUser = -1;
						}
						return true;
					},

					function (connectionInstance){

					}
				);
			}else{
				// it's an email
				ajax.post('/api/processors/messaging',
					{
						type: 'sendEmail',
						subject: subject,
						message: message,
						userId: email.composeMailToUser
					},

					function (connectionInstance){
						if (connectionInstance.serverResponse == 'ok'){
							client.windows.myMail.__tab('inbox');
							client.userNotice('E-mail', 'E-mail sent successfully.');
							email.composeMailToUser = -1;
						}
						return true;
					},

					function (connectionInstance){

					}
				);
			}
		},

		/**
			Remove the message from the clients view
		**/
		removeMessage: function(index){

			index = parseInt(index);

			var w = getObject('inbox_content');	// content window
			var p = getObject('inbox_list'); // parent

			w.innerHTML = '';

			// remove from list
			var c = getObject('email_' + email.emailBox + "_" + index);
			//p.removeChild(c);

			email.emailsObj.splice(index,1);
			email.buildEmailListFilter();
			// reset our selected email index
			email.selectedEmail = null;

			// select the previous mail in list
			if ((index-1) <= 0){
				email.showEmailContent(0);
				email.setSelected(0);
			}else{
				email.showEmailContent(index-1);
				email.setSelected(index-1);
			}
		},

		deleteMessage: function(index){
			var e = email.emailsObj[index];
			var type = '';
			var id = '';

			if (e.cirkitConnectId){
				type = 'deleteCirkitConnect';
				id = e.cirkitConnectId;
				email.ccCount--;
			}else if (e.contactRequestId){
				type = 'deleteContactRequest';
				id = e.contactRequestId;
				email.crCount--;
			}else if (e.emailId){
				type = 'deleteEmail';
				id = e.emailId;
				email.emailCount--;
			}else if (e.announcementId){
				type = 'deleteAnnouncement';
				id = e.announcementId
				email.annCount--;
			}else{
				client.userError('E-mail', 'Invalid action.');
			}

			ajax.post('/api/processors/messaging',
				{
					type: type,
					id: id
				},

				function (connectionInstance) {
					if (connectionInstance.serverResponse == 'true'){
						email.removeMessage(index);
					}
					return true;
				},

				function (connectionInstance) {
					client.userError('E-mail', 'Request failed. Please try again.');
				}

			);
		},

		deletePopMessage: function(index){
			if (index < 0) return false;

			var id = email.popEmails[index].popEmailId;

			ajax.post('/api/processors/messaging',
				{
					type: 'deletePopMessage',
					id: id
				},

				function (connectionInstance) {
					if (connectionInstance.serverResponse == 'ok'){
						email.removePopMessage(index);
					}
					return true;
				},

				function (connectionInstance) {
					client.userError('E-mail', 'Request failed. Please try again.');
				}

			);
		},

		removePopMessage: function(index){

			if (index < 0) return false;

			index = parseInt(index);

			var w = getObject('inbox_content');	// content window
			var p = getObject('inbox_list'); // parent

			w.innerHTML = '';

			// remove from list
			var c = getObject('pop_' + index);
			p.removeChild(c);
			email.popEmails.splice(index,1);
			email.buildPopEmailList();

			// reset our selected email index
			email.selectedPopEmail = null;

			// select the previous mail in list
			if ((index-1) == 0){
				email.showPopEmailContent(0);
				email.setPopSelected(0);
			}else{
				email.showPopEmailContent(index-1);
				email.setPopSelected(index-1);
			}

		},

		setPopSelected: function(index){
			if (email.selectedPopEmail != null){
				var selected = getObject("pop_" + email.selectedPopEmail);
				if (selected){
					var tmpClass = selected.className;
					tmpClass = tmpClass.replace("selected", "");
					selected.className = tmpClass;
				}
			}

			var e = getObject("pop_" + index);
			e.className += ' selected ';
			email.selectedPopEmail = index;
		},

		reload: function(){
			// handle the inbox
			if (client.windows.myMail.selectedTab.id == 'inbox'){
				this.forceReload = true;
				this.boxSwitcher();
			}
		},
		cleanMCE: function(){
			var editorId = getMCEEditorId('composeMailMessage');
			if (!isEmpty(editorId)){
				destroyMCEInstance('composeMailMessage');
			}
		}

	}
function fetchUserVault(){
	if(client.data.profileVault)return true;
	var post = {
		type:"getVault",
		i:client.getBrowseUserID()
	};
		ajax.post("/api/processors/user",
			post,
	 		function( conn ){
	 			if(conn && conn.responseObject && conn.responseObject.error){
					switch( conn.responseObject.error ){
						case '6675':
								getObject('vaultCanvas').innerHTML = '<table height="100%" width="100%"><tbody><tr><td height="100%" width="100%" align="center"><img src="/images/perms/windshield.png"  width="100%" /></td></tr></tbody></table>';
								return false;
							break;
					}
				}else if(conn.responseObject){
	 				client.windows.windshield.setLoading(true);
	 				client.windows.windshield.setStatus("Building Vault . . .");
	 				client.data.profileVault = conn.responseObject;
	 				buildVaultPane( dh.nodes.vaultCanvas , client.data.profileVault,true);
	 			}else{
	 				
	 			}
	 		},
	 		null,
	 		client.windows.windshield);
}
function buildVaultPane( dhCont , dataList,purge){
	if(purge)dhCont.purge();
	var buildTo = null;
	if((buildTo = dh.nodes.hiddenVault)){
		buildTo.destroy();
	}
	setTimeout(
		function(){
			buildTo = dh.createDHObject("div","hiddenVault","r o f",canvasStorage,dhNull,hidden);

			var dataList = getArrayCpy(client.data.profileVault["folders"]);
			buildVaultFolders(buildTo , dataList);

			dataList = getArrayCpy(client.data.profileVault["files"]);
			buildVaultFiles(buildTo , dataList);

			buildTo.setDHParent(dhCont);
			buildTo.show();

	 		client.windows.windshield.setStatus("Idle");
	 		client.windows.windshield.setLoading(false);
		},0);
}

function buildVaultFolders(dhCont , dataList){
	var htmlCont = dhCont.obj;
	var currCont = htmlCont;
	var wrkDir = -1;
	var stackA = dataList;
	var stackB = [];
	var currFolders = [];
	var currStack = stackA;
	var nextStack = stackB;
	var postClass = 'postA';
	var margin = 0;

	dhCont.type = 'userVault';

	var header = dh.createDHObject("div","hiddenVaultHeader","bookmarkFolderInfoRow",htmlCont,dhNull,none);
	buildVaultHeader(header);

	while(currStack.length){
		if(currStack == stackA){
			nextStack = stackB;
		}else{
			nextStack = stackA;
		}
		var data = currStack.pop();
		if(data.parent != wrkDir){
			nextStack.push(data);
		}else{
			var row = dh.createDHObject("div",dhCont.id+"_"+data.type+"_"+data.id,'',currCont,dhNull,dhNull);
				row.bookmarkData = data;
				row.margin = (dh.$(row.obj.parentNode.id).type == "userVault")? 0 : dh.$(row.obj.parentNode.parentNode.id).margin + 20 ;
				row.listPane = dhCont;
				buildVaultFolder( row , data , postClass);
				row.obj.className = "bookmarkFolder";
				currFolders.push({id:data.id,htmlCont:row.obj.childNodes[1]});
				showObject(currCont);
				hideObject(currCont);
		}

		postClass = (postClass == 'postA')? 'postB' : 'postA';
		if(!(currStack.length)){
			if(nextStack.length){
				if(currFolders.length){
					var nextFolder = currFolders.pop();
					currCont = nextFolder.htmlCont;
					wrkDir = nextFolder.id;
				}
				currStack = nextStack;
			}
		}
	}
}
function buildVaultFiles(dhCont , dataList){
	var postClass = 'postA';
	for(key in dataList){
		var data = dataList[key];
		var currDHCont = dhCont;
		if(data.parent > 0){
			currDHCont = dh.$(dhCont.id+"_dir_"+data.parent+"_childRow");
		}

		if(!currDHCont){return false};
		var currCont = currDHCont.obj;

		var row = dh.createDHObject("div",dhCont.id+"_"+data.type+"_"+data.id,'',currCont,dhNull,dhNull);
			row.bookmarkData = data;
			row.margin = (dh.$(row.obj.parentNode.id).type == "userVault")? 0 : dh.$(row.obj.parentNode.parentNode.id).margin + 20 ;
			row.listPane = dhCont;

		buildVaultFile( row ,data , postClass);
		row.obj.className = "bookmarkFile";
		postClass = (postClass == 'postA')? 'postB' : 'postA';
		currDHCont.showNow();
		currDHCont.hideNow();
	}
}

function buildVaultHeader(dhCont){
	var htmlCont = dhCont.obj;

	var infoRow = createObject("div",dhNull,"bookmarkFileInfoRow",htmlCont,dhNull);
	var Description = createObject("div",dhNull,"bookmarkCell",infoRow,dhNull);
	var spacer = createObject("div",dhNull,"fl fv spacer",Description,dhNull);
	var desc = createObject("div",dhNull,"fl fv active",Description,"File Name");
	var DateAdded = createObject("div",dhNull,"bookmarkCell",infoRow,"Date Added");
	var Url = createObject("div",dhNull,"bookmarkCell",infoRow,"Size");
}

function buildVaultFolder( dhCont , data ,postClass){
	var htmlCont = dhCont.obj;


	var infoRow = dh.createDHObject("div",htmlCont.id+"_infoRow","bookmarkFolderInfoRow p",htmlCont,dhNull,none);
	var childrenRow = dh.createDHObject("div",htmlCont.id+"_childRow","bookmarkChildRow",htmlCont,dhNull,hidden);

	var Description = createObject("div",dhNull,"bookmarkCell",infoRow.obj,dhNull);
	var spacer = createObject("div",dhNull,"fl fv spacer",Description,dhNull);
	var desc = createObject("div",dhNull,"fl fv",Description,dhNull);
	var carot = createObject("div",dhNull,"fl fv treeCarot",desc,dhNull);
	var folderName = createObject("div",dhNull,"fl fv",desc,data["Description"]);

	var DateAdded = createObject("div",dhNull,"bookmarkCell",infoRow.obj,data["Date Added"]);
	var Url = createObject("div",dhNull,"bookmarkCell",infoRow.obj,data["Url"]);

	spacer.style.width = dhCont.margin+"px";

	infoRow.obj.className += " "+postClass;
	infoRow.obj.onclick=function(){
		if(childrenRow.visible){
			childrenRow.hide();
			//childrenRow.slide(-1);
			carot.style.backgroundImage = "url(" + ecirkitImagesURL + "tree_collapsed.png)";
		}else {
			childrenRow.show();
			//childrenRow.slide(0);
			carot.style.backgroundImage = "url(" + ecirkitImagesURL + "tree_expanded.png)";
		}
	}
/*	childrenRow.slide = function( dy ){
		infoRow.bringToFront();
		if(dy >= 0){childrenRow.show();}
		var height = childrenRow.getH();
		if(dy >= 0){childrenRow.moveTo(dhNull,(-height));}

		dy = (dy < 0)? (dy * height) : 0;
		childrenRow.animate(new dh.tweenDetails( dhNull ,dy,dhNull, dhNull,100, .5, 5),
			function(){
				if(dy < 0){
					childrenRow.hide();
				}else{
					childrenRow.obj.style.top="0px";
				}
			});
	}*/
}

function buildVaultFile( dhCont ,data, postClass ){
	var htmlCont = dhCont.obj;
	postClass = "postA";
	if(htmlCont != htmlCont.parentNode.firstChild){
		var last = htmlCont.previousSibling.firstChild;
		if(last.className.replace(/.*(postA).*/,'$1') == "postA"){
			postClass = "postB";
		}
	}

	dhCont.infoRow = createObject("div",dhNull,"bookmarkFileInfoRow",htmlCont,dhNull);
	dhCont.Description = createObject("div",dhNull,"bookmarkCell",dhCont.infoRow,dhNull);
	dhCont.spacer = createObject("div",dhNull,"fl fv spacer",dhCont.Description,dhNull);
	dhCont.desc = createObject("div",dhNull,"fv active",dhCont.Description);
	dhCont.desc.innerHTML = '<a href="/api/servlets/vault?uid='+client.getBrowseUserID()+'&vid='+data["id"]+'" target="_blank">'+data["File Name"]+'</a>';
	dhCont.DateAdded = createObject("div",dhNull,"bookmarkCell",dhCont.infoRow,prepDate(data["Date Added"]));
	dhCont.Url = createObject("div",dhNull,"bookmarkCell",dhCont.infoRow,data["Size"]);


	dhCont.infoRow.onmouseover = function(){
		descriptionPop(data.description);
	}
	dhCont.infoRow.onmouseout = unregisterToolTip;

	dhCont.spacer.style.width = dhCont.margin+"px";
	dhCont.desc.style.marginLeft = dhCont.margin+"px";
	dhCont.Description.style.clear = "left";
	dhCont.infoRow.className += " "+postClass;
}
function buildRemark(objId,data,replyType,deleteType,b,ed){

	var remark = dh.$(objId);
	var c = null;
	if(!remark){
		if(!getObject(objId))return false;
		else
		remark = dh.addObject(objId,none);
	}
	if(data){
		remark.remarkData = data;
		c = data;
	}else{
		if(remark.remarkData)
			c = remark.remarkData;
		else
			return false;
	}
	remark.replyFunc = replyToRemark;
	remark.deleteFunc = deleteRemark;
	if(replyType)
		remark.replyType = replyType;
	if(deleteType)
		remark.deleteType = deleteType;

	remark.purge();
	var remarkTable = createObject("table",'','fh',remark.obj,'');
	var remarkTbody = createObject("tbody",'','',remarkTable,'');
	var remarkTrow = createObject("tr",'','',remarkTbody,'');
	var remarkTAvatarCell = createObject("td",'','remarkTAvatarCell',remarkTrow,'');
	var remarkTRemarkCell = createObject("td",'','remarkTRemarkCell',remarkTrow,'');
		remarkTAvatarCell.setAttribute("valign", "top");
		remarkTRemarkCell.setAttribute("valign", "top");

		remarkTAvatarCell.setAttribute("vAlign", "top");
		remarkTRemarkCell.setAttribute("vAlign", "top");
		remarkTAvatarCell.align = "left";

	var avatarPane = createObject("div",'','profileRemarkAvatar',remarkTAvatarCell,'');
	displayUserAvatar( avatarPane, {
		user_id:c.commenterUserId,
		userName:c.displayName,
		online:c.online
	}, false, true, false );

	var remarkCellHTML = "<div id='"+objId+"_remark_Pane_"+c.remarkId+"' class='profileRemarkPane'>"+
							"<div class='profileRemarkRemark'>"+
								"<div class='profileRemarkDate'>"+
									c.displayName+" left a remark at "+prepDate(c.dateCreated)+
								"</div>"+
								"<div class='profileRemarkText gts'>"+
									prepMessage(c.message,true,false,false)+
								"</div>"+
							"</div>";
	if(c.replyMessage){
		remarkCellHTML += "<div class='profileRemarkReply'>"+
							'<div class="r" style="height:2px;background:white url(/images/themes/launch/window_white_opaque.jpg) no-repeat scroll 0px -50px;"></div>'+
							"<div class='profileRemarkReplyDate'>"+
								client.getBrowseUserObject().profile_info.display_name+" replied at "+prepDate(c.replyDate)+
						"</div>"+
							"<div class='profileRemarkReplyText gts'>"+
								prepMessage(c.replyMessage,true,false,false)+
							"</div></div>"
	}
	remarkCellHTML += "</div>";
	remarkTRemarkCell.innerHTML = remarkCellHTML;
	if(client.isHomeProfile() || ed){
		var replyType = '';
		if(c.replyMessage){
			optType = 'Edit Reply';
		}else{
			optType = 'Reply';
		}
		var optDiv = createObject("div",'','remarkOptWrap',remark.obj,'');
		var optHTML =

						'<div onclick="dh.$(\''+objId+'\').deleteFunc();" class="actionIconWrapper">'+
							'<div class="actionIcon icon16 xCircleTan16"></div><div class="actionIconText16">'+
								'DELETE'+
							'</div>'+
						'</div>'+

						'<div onclick="dh.$(\''+objId+'\').replyFunc();" class="actionIconWrapper">'+
							'<div class="actionIcon icon16 editIcon16"></div><div class="actionIconText16">'+
								optType+
							'</div>'+
						'</div>';
		optDiv.innerHTML = optHTML;
	}
	remark.obj.className += (b)? " profileRemarkB" : " profileRemarkA" ;
}

function deleteRemark(){
	var msg = 'This will <font style="color:red">PERMANENTLY</font>  delete this remark.'
					+'<br /> Are You Sure You Want To Do This?';
	var remark = this;
	var promtp = new ePromptIt("Delete Remark?", msg,
		function( response ){
			switch( response ) {
				case promptButtons.yesNo.yes:
					sendRemarkDelete(remark);
					break;
				case promptButtons.yesNo.no:
					break;
			}
		},
		promptButtons.yesNo,
		promptThemes.question);
}
function replyToRemark(){
	var data = this.remarkData;
	var cId = this.id;
	var dataList = dh.$(this.obj.parentNode.id).remarkDataList;

	//var index = dataList.indexOf(data);
	var remarkPane = getObject(cId+"_remark_Pane_"+data.remarkId);
	var replyPane;
	if(remarkPane.childNodes.length >= 2){
		replyPane = remarkPane.lastChild;
	}else{
		replyPane = createObject("div","","profileRemarkReply",remarkPane,'');
	}
	var replyHTML = "<div class='profileRemarkDate'>"+
						((data.replyDate)? prepDate(data.replyDate): '')+
						"<div class='profileRemarkButtons'>"+
							"<div class='active fr' style='margin-left:5px;' onclick='buildRemark(\""+cId+"\")'>[Cancel]</div>"+
							"<div class='active fr' onclick='sendProfileReply(\""+cId+"\")'>[Send Reply]</div>"+
						"</div>"+
					"</div>"+
						"<div class='profileRemarkReplyText'>"+
							"<textarea onkeyup='saveProfileReply(this.value,\""+cId+"\")' class='profileRemarkReplyTextArea'>"+
								((data.replyMessage)? (data["newReply"] = prepMessage(data.replyMessage,true,false,false)) : '')+
							"</textarea>"+
						"</div>";
	replyPane.innerHTML = replyHTML;

}
function saveProfileReply(value,cId){
	var data = dh.$(cId).remarkData;
		data["newReply"] = value;
}
function sendProfileReply( cId ){
	var remark = dh.$(cId);
	var list = dh.$(remark.obj.parentNode.id);
	var data = remark.remarkData;
	var post = {
		type:remark.replyType,
		cid:data.remarkId,
		comment:data["newReply"]
	}
		ajax.post("/api/processors/user",
			post,
	 		function( conn ){
	 			if(conn.serverResponse != 'false'){
	 				data.replyDate = conn.serverResponse;
	 				data.replyMessage = data.newReply;
	 				buildRemark( cId );
	 			}else{}
	 			buildRemark( cId );
	 			return true;
	 		},
	 		null,
	 		list.win);
}
function sendRemarkDelete(remark){
	var dataList = dh.$(remark.obj.parentNode.id).remarkDataList;
	var win = dh.$(remark.obj.parentNode.id).win;
	var data = remark.remarkData;
	var post = {
		type:remark.deleteType,
		cid:data.remarkId
	}
		ajax.post("/api/processors/user",
			post,
	 		function( conn ){
	 			var remarksArray = dataList;
	 			remark.destroy();
	 			remarksArray.splice( indexOf ( remarksArray, data ),1);
	 			return true;
	 		},
	 	null,
	 		win);
}
function leaveRemark( type , cid,listId,callWin){

	client.windows.leaveRemark.remarkType = type;
	client.windows.leaveRemark.cid = cid;
	client.windows.leaveRemark.listId = listId;
	client.windows.leaveRemark.callWin = callWin;
	if(!client.isLoggedIn()){
		client.login_logout(true,remarkLoginCallback);
	}else{
		remarkLoginCallback("success");
	}

}
function remarkLoginCallback( response ){
	if(response == "success" && client.isLoggedIn()){
		if(client.getBrowseUserID() == client.loggedInID){
			client.userError("No Way Jose!","You Can Not Leave A Remark On Your Own Profile");
			return false;
		}
		client.showWorkspaceMatte();
		client.windows.leaveRemark.show();
	}else{
		client.userError("Cannot open window", "The window you are typing to open requires a login. Please log in to open this window.");
		client.windows.leaveRemark.minimize();
	}
}

function sendLeaveRemark(){
	var area = getObject("leaveRemarkTextArea");
	var data = area.value;
	var post = {
		type:client.windows.leaveRemark.remarkType,
		i:client.getBrowseUserID(),
		cid:client.windows.leaveRemark.cid,
		comment:data
	}
		ajax.post("/api/processors/user",
			post,
	 		function( conn ){
				try{
		 			if(conn.responseObject){
		 				var c = conn.responseObject;
						if(client.windows.leaveRemark.listId){
							var remark = createObject("div",client.windows.leaveRemark.listId+'_remark_'+c.comment_id,'profileRemark',dhNull,'');

							var dhList = dh.$(client.windows.leaveRemark.listId);
							var list = dhList.obj;
								if(!(dhList.remarkDataList)){
									client.data[client.windows.leaveRemark.listId] = [];
									dhList.remarkDataList = client.data[client.windows.leaveRemark.listId];
									dhList.purge();
								}
								dhList.remarkDataList.unshift(c);

							list.insertBefore(remark,list.firstChild);
							remark = dh.addObject(client.windows.leaveRemark.listId+'_remark_'+c.comment_id);

							buildRemark(client.windows.leaveRemark.listId+'_remark_'+c.comment_id,c);
						}
		 			}
				}catch(ex){}
	 			area.value =  '';
	 			area.innerHTML = '';
	 			client.windows.leaveRemark.__close();
	 			return true;
	 		},
	 		null,
	 		client.windows.leaveRemark.callWin);
}
/***********************************************
 *
 * AJAX Functionality
 *
 * 		{
 * 			successful: false,
 * 			messages:
 * 				[
 * 					{ code:		1564, message: 	'Email Address Invalid' },
 * 					{ code:		1562, message: 	'No Zip Code' },
 * 					{ code:		1564, message: 	'Yo momz is too crazy' }
 * 				]
 * 		}
 *
 *
 *
 *
 *
 *		ajax.post('/' + path + '/Hookup.cmd',
 *			{
 *				type : 'Hookup',
 *				id1: id1,
 *				id2: id2,
 *				msg: text
 *			},
 *			function (connectionInstance){
 *				var response = connectionInstance.responseObject;
 *				if( response ){
 *					if(response.successful){
 *						if( response.messages ){
 *							displayResponseObject( response );
 *						} else {
 *							showMsg("Cirkit Connect", "Your Cirkit Connect has been sent." , false);
 *							endHookup();
 *						}
 *					} else {
 * 						//here we can return false, and ajax will call the onError function for us
 * 						// but for this instance that is only used for system errors.
 *						displayResponseObject(response);
 *					}
 *
 *				} else {
 *					showMsg("Cirkit Connect", "The server returned no data. Please try again." , true);
 *				}
 *			},
 *			function (connectionInstance){
 *				showMsg("Cirkit Connect", "There was an unexpected error while processing your request." , true);
 *			}
 *		);
 *	}
 *
 *
 ***********************************************/
var GET = 'get';
var POST = 'post';
var ajax;
function Ajax() {
	this.connections = [];
	this.currentRequest = null;
}
Ajax.prototype = {
	get: function(url, requestObject, onSuccess, onError, dataWindow, showLoadingIcon){
		var req = new HTTP( GET, url, requestObject, onSuccess, onError, dataWindow, showLoadingIcon  );
		this.queueRequest(req);
	},
	post: function (url, requestObject, onSuccess, onError, dataWindow, showLoadingIcon){
		var req = new HTTP( POST, url, requestObject, onSuccess, onError, dataWindow, showLoadingIcon  );
		this.queueRequest(req);
	},

	//----------------------------------------
	// Auto-queue?
	//----------------------------------------
	runNext : function (){
		if( this.paused ) return false;					//can't run the queue if we're paused


		//this is a check to ensure 1 request happens at a time.
		//it's now disbaled because it may not be useful at all but i'll leave it here as an option
		//if( this.currentRequest ) return false;			//we already got one running


		var req = this.getNextRequest();
		if( req ){
			this.currentRequest = req;					//save the current request

			//new thread from here.
			setTimeout ( function () { req.commit() } , 0);
		}
	},

	queueRequest : function ( newRequest ){
		if( this.paused ) return false;					//do not accept new requests when paused. - for polling
		this.connections.unshift( newRequest );
		this.runNext();
	},

	getNextRequest : function (){
		var next = this.connections.pop();
		return ( next ) ? next : false;
	},

	pause : function(){
		this.paused = true;
	},

	resume : function (){
		this.paused = false;
		this.runNext();
	},

	clear : function (){
		this.connections = [];
	}
}

var http_100 = { value: 100, description: "Continue"};
var http_101 = { value: 101, description: "Switching protocols"};
var http_200 = { value: 200, description: "Switching protocols"};
var http_201 = { value: 201, description: "Created"};
var http_202 = { value: 202, description: "Accepted"};
var http_203 = { value: 203, description: "Non-Authoritative Information"};
var http_204 = { value: 204, description: "No Content"};
var http_205 = { value: 205, description: "Reset Content"};
var http_206 = { value: 206, description: "Reset Content"};
var http_300 = { value: 300, description: "Multiple Choices"};
var http_301 = { value: 301, description: "Moved Permanently"};
var http_302 = { value: 302, description: "Found"};
var http_303 = { value: 303, description: "See Other"};
var http_304 = { value: 304, description: "Not Modified"};
var http_305 = { value: 305, description: "Use Proxy"};
var http_307 = { value: 307, description: "Temporary Redirect"};
var http_400 = { value: 400, description: "Bad Request"};
var http_401 = { value: 401, description: "Unauthorized"};
var http_402 = { value: 402, description: "Payment Required"};
var http_403 = { value: 403, description: "Forbidden"};
var http_404 = { value: 404, description: "Not Found"};
var http_405 = { value: 405, description: "Method Not Allowed"};
var http_406 = { value: 406, description: "Not Acceptable"};
var http_407 = { value: 407, description: "Proxy Authentication Required"};
var http_408 = { value: 408, description: "Request Timeout"};
var http_409 = { value: 409, description: "Conflict"};
var http_410 = { value: 410, description: "Gone"};
var http_411 = { value: 411, description: "Length Required"};
var http_412 = { value: 412, description: "Precondition Failed"};
var http_413 = { value: 413, description: "Request Entity Too Large"};
var http_414 = { value: 414, description: "Request-URI Too Long"};
var http_415 = { value: 415, description: "Unsupported Media Type"};
var http_416 = { value: 416, description: "Requested Range Not Suitable"};
var http_417 = { value: 417, description: "Expectation Failed"};
var http_500 = { value: 500, description: "Internal Server Error"};
var http_501 = { value: 501, description: "Not Implemented"};
var http_502 = { value: 502, description: "Bad Gateway"};
var http_503 = { value: 503, description: "Service Unavailable"};
var http_504 = { value: 504, description: "Gateway Timeout"};
var http_505 = { value: 505, description: "HTTP Version Not Supported"};

function HTTP( method, url, requestObject, onSuccess, onError, dataWindow, showLoadingIcon ){
	//all defaults
	this.key = 				this.makeKey();
	this.method = 			method;
	this.url = 				url;
	this.httpStatus = 		null;
	this.requestObject = 	(requestObject) ? requestObject : null;
	this.serverResponse = 	"";
	this.responseObject = 	null;
	this.onError = 			onError;
	this.onSuccess =		onSuccess;
	this.dataWindow = 		dataWindow;
	this.showLoadingIcon = 	( isEmpty(showLoadingIcon) ) ? true : false ;

	return this;
}
HTTP.prototype = {
	/*********************************
	 * AJAX Functions - Doc comming soon
	**********************************/
	createHTTP: function (){
		if(typeof XMLHttpRequest != "undefined"){ return new XMLHttpRequest(); }
		else if( window.ActiveXObject ) {
			var testObj = [
				"MSXML2.XMLHttp.5.0",
				"MSXML2.XMLHttp.4.0",
				"MSXML2.XMLHttp.3.0",
				"MSXML2.XMLHttp",
				"Microsoft.XMLHttp.5.0"
			];
			for( var i = 0; i < testObj.length; i++){
				try{
					var xmlObj = new ActiveXObject(testObj[i]);
					return xmlObj;
				}
				catch( err ){  }
			}
		}
		return false;
		//return new XMLHttpRequest;
	},

	//ajax connection key generator
	makeKey: function(){
		var date = new Date();
		return 	date.getHours() + "" + date.getMinutes() + "" + date.getSeconds() + "" + date.getMilliseconds();
	},

	commit: function() {
		var ohttp = this.createHTTP();
		var connectionInst = this;
		this.request = this.serializeData(this.requestObject);	//serialized request

		try{
			if(this.dataWindow && this.showLoadingIcon ) this.dataWindow.setLoading(true);

			ohttp.open( this.method, this.url, true );

			if(this.method == POST){ 	//posting requires some headers
				ohttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
				ohttp.setRequestHeader("Content-length", this.request.length);
				ohttp.setRequestHeader("Connection", "close");
			}

			ohttp.onreadystatechange = function () {
				var success = true;
				switch (ohttp.readyState){
					case 0: //Uninitialized
						break;
					case 1: //Open
						if(connectionInst.dataWindow) connectionInst.dataWindow.setStatus("Connected");
						break;
					case 2: //Sent
						if(connectionInst.dataWindow) connectionInst.dataWindow.setStatus("Sending request");
						break;
					case 3: //Receiving
						if(connectionInst.dataWindow) connectionInst.dataWindow.setStatus("Receiving Data");
						break;
					case 4: //Loaded
						if(connectionInst.dataWindow) connectionInst.dataWindow.setStatus("Reading Result");
						connectionInst.httpStatus = ohttp.status;

						if(connectionInst.httpStatus == http_200.value) {

							//gathering info
			                connectionInst.serverResponse = ohttp.responseText;
							connectionInst.responseObject = JSON.parse(ohttp.responseText);

							//disable the loading icon
			              	if(connectionInst.dataWindow){
		              			if( connectionInst.showLoadingIcon ) connectionInst.dataWindow.setLoading(false);
			               		connectionInst.dataWindow.setStatus("Idle");
			               	}

							//server error check
							if( connectionInst.responseObject ){
								if( connectionInst.responseObject.success == false ){
									//there was a server error response.
									success = false;
									try{ client.processError(connectionInst.responseObject); }
									catch ( ex ) {if(ex=="perms")success = true;}

								}
							}
						}

						if( success ) {
			               	//call onSuccess,
			               	// if we get a false, go to
							if(connectionInst.onSuccess){
								if( !connectionInst.onSuccess(connectionInst) ) {
								}
							}

			           	} else {

			              	if(connectionInst.dataWindow){
		              			if( connectionInst.showLoadingIcon ) connectionInst.dataWindow.setLoading(false);
			               		connectionInst.dataWindow.setStatus("Server Error");
								setTimeout( function () { connectionInst.dataWindow.setStatus('Idle'); }, 5000 );
			               	}
			            	if(connectionInst.onError){
			            		connectionInst.onError(connectionInst);
			            	}

						}

						try{
							ajax.currentRequest = null;
							ajax.resume();
						} catch (ex){}

						break;
					default:
						break;
				}
		    };

		    //send the post data if posting
		    ohttp.send(
		    	(this.method == POST) ?
		    		"&" + this.request:
		    		null //otherwise null
		    );
			return true;
		} catch(ex) {
			if( isString(ex) ){
				//alert(ex);
				return false;
			}

			
		}
	    return false;
	},

	/*************************************************
		Encodes text for url and removes javascript
	**************************************************/
	setData : function (newData){
		this.requestObject = this.serializeData(newData);
	},

	serializeData: function (dataObject){
		var data = "";
		var amp = "";
		for(var valueID in dataObject){
			data += amp + valueID +  "=" + this.encode( dataObject[valueID] );
			amp = "&";
		}

		return data;
	},
	encode: function(val){
		return prepMessage(val);
	},
	decode: function(rootElement){
		if(rootElement == dhNull){
			rootElement = this.responseObject; //start from the bottom up
		}
		for(var valueID in rootElement){
			var elem = rootElement[valueID];
			switch( typeof(elem) ){
				case 'string':
					elem = prepMessage( elem, true);
					rootElement[valueID] = elem;
					break;
				case 'object':
				case 'array':
					if(elem != null) this.decode(elem);
					break;
				default:
					break;
			}
		}
	},
	cleanJavascript: function(str){
		str = str.replace(/\<script.*?\>.*?\<\/script\>/g, '');
		str = str.replace(/<[^>]*="javascript:[^"]*"[^>]*>/g, '');
		return str;
	},
	makeUrlsClickable : function (str){
		return str.replace(/(https:\/\/|http:\/\/|ftp:\/\/|www\.)([^\s]*)/gi,'<a href="http://$2" target="_blank">$1$2</a>');
	}
}

/*************************************************
	Makes email/bulletin/comment
	message proper for storage and display
**************************************************/
function prepMessage(msg, decode, formatUrls){
	if (isEmpty(msg)) return "";
	msg = String(msg);
	if (decode){
		while (msg != unescape(msg)) msg = unescape(msg);
		msg = unescape(msg);
		try {
			msg = decodeURIComponent(msg);
		} catch (ex) {
        	//?
		}
		//if(!isEmpty(formatUrls)) msg = makeUrlsClickable(msg);
	}else{
		// replace all <br /> tags generated by fckEditor
		//msg = msg.replace(/<br \/>/g, '');

		// convert all new lines/carriage returns to a line break
		msg = msg.replace(/\r\n|\r|\n/g, '<br />');
		//msg = msg.replace(/\n|\r\n/g, '<br />');

		// strip all javascript
		msg = cleanJavascript(msg);

		// escape the result
		msg = escape(msg);
	}
	return msg;
}

function htmlspecialchars_decode( input ){
	input = input.replace( /&amp;/gi, "&");
	input = input.replace( /&quot;/gi,"\"");
	input = input.replace( /&#039;/gi,"'");
	input = input.replace( /&lt;/gi, 	"<");
	input = input.replace( /&gt;/gi, 	">");
	return input;
}
function htmlspecialchars_encode( input ){
	input = input.replace( "&",  "&amp;");
	input = input.replace( /"/g, "&quot;");
	input = input.replace( /'/g, "&#039;");
	input = input.replace( "<",  "&lt;");
	input = input.replace( ">",  "&gt;");
	return input;
}
function htmlspecialchars_bitcode( input ){
	input = input.replace( "&",  "&amp;");
	input = input.replace( /"/g, "\\&quot;");
	input = input.replace( /'/g,	 "\\&#039;");
	input = input.replace( "<",  "&lt;");
	input = input.replace( ">",  "&gt;");

	return input;
}
/**********************************************
	Functions for cleaning all text elements
	* Both encoding and decoding
**********************************************/
function cleanJavascript(str){
	str = str.replace(/\<script.*?\>.*?\<\/script\>/g, '');
	str = str.replace(/<[^>]*="javascript:[^"]*"[^>]*>/g, '');
	return str;
}
function makeUrlsClickable(str){
	var index = parseInt(str.search(/(&lt;|<)([aA].*)([^\s]*)/));

	if(index >= 0){
		return parseAnchorTag(str,index);
	}

	return str.replace(/(https:\/\/|http:\/\/|ftp:\/\/|www\.)([^\s]*)/gi,'<a href="http://$2" target="_blank">$1$2</a>');
}
function parseAnchorTag(str,startTag){
	var endTag = parseInt((str.search(/(&lt;|<)\/a(&gt;|>)/)))+10;
	var formerStr = makeUrlsClickable(str.substring(0,startTag-1));
	var latterStr = makeUrlsClickable(str.substring(endTag));

	var anchorTag = str.substring(startTag,endTag).replace(/(&lt;|<)[aA].*href=&quot;((https:\/\/|http:\/\/|ftp:\/\/|www\.)([^\s]*))&quot;.*(&gt;|>)(.*)(&lt;|<)\/a(&gt;|>)/,"<a href='http://$4'>$6</a>");
	return formerStr+anchorTag+latterStr;
}
function cleanMarkup(html) {
	html = html.replace(/<o:p>\s*<\/o:p>/g, "") ;
	html = html.replace(/<o:p>.*?<\/o:p>/g, "&nbsp;") ;

	// Remove mso-xxx styles.
	html = html.replace( /\s*mso-[^:]+:[^;"]+;?/gi, "" ) ;

	// Remove margin styles.
	html = html.replace( /\s*MARGIN: 0cm 0cm 0pt\s*;/gi, "" ) ;
	html = html.replace( /\s*MARGIN: 0cm 0cm 0pt\s*"/gi, "\"" ) ;
	html = html.replace( /\s*TEXT-INDENT: 0cm\s*;/gi, "" ) ;
	html = html.replace( /\s*TEXT-INDENT: 0cm\s*"/gi, "\"" ) ;
	html = html.replace( /\s*TEXT-ALIGN: [^\s;]+;?"/gi, "\"" ) ;
	html = html.replace( /\s*PAGE-BREAK-BEFORE: [^\s;]+;?"/gi, "\"" ) ;
	html = html.replace( /\s*FONT-VARIANT: [^\s;]+;?"/gi, "\"" ) ;
	html = html.replace( /\s*tab-stops:[^;"]*;?/gi, "" ) ;
	html = html.replace( /\s*tab-stops:[^"]*/gi, "" ) ;

	// Remove Class attributes
	html = html.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3");

	// Remove empty styles.
	html = html.replace( /\s*style="\s*"/gi, '' );
	html = html.replace( /<SPAN\s*[^>]*>\s*&nbsp;\s*<\/SPAN>/gi, '&nbsp;' );
	html = html.replace( /<SPAN\s*[^>]*><\/SPAN>/gi, '' );

	// Remove Lang attributes
	html = html.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3");
	html = html.replace( /<SPAN\s*>(.*?)<\/SPAN>/gi, '$1' );
	html = html.replace( /<FONT\s*>(.*?)<\/FONT>/gi, '$1' );

	// Remove XML elements and declarations
	html = html.replace(/<\\?\?xml[^>]*>/gi, "");
	html = html.replace(/<\/?\w+:[^>]*>/gi, "");

	// Remove comments [SF BUG-1481861].
	html = html.replace(/<\!--.*-->/g, "");
	html = html.replace( /<H\d>\s*<\/H\d>/gi, '' );
	html = html.replace( /<H1([^>]*)>/gi, '<div$1><b><font size="6">' );
	html = html.replace( /<H2([^>]*)>/gi, '<div$1><b><font size="5">' );
	html = html.replace( /<H3([^>]*)>/gi, '<div$1><b><font size="4">' );
	html = html.replace( /<H4([^>]*)>/gi, '<div$1><b><font size="3">' );
	html = html.replace( /<H5([^>]*)>/gi, '<div$1><b><font size="2">' );
	html = html.replace( /<H6([^>]*)>/gi, '<div$1><b><font size="1">' );
	html = html.replace( /<\/H\d>/gi, '<\/font><\/b><\/div>' );

	// Remove empty tags (three times, just to be sure).
	html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' );
	html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' );
	html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' );

	// Transform <P> to <DIV>
	var re = new RegExp( "(<P)([^>]*>.*?)(<\/P>)", "gi" );	// Different because of a IE 5.0 error
	html = html.replace( re, "<div$2<\/div>" );

	// Fix relative anchor URLs (IE automatically adds the current page URL).
	re = new RegExp( window.location + "#", "g" );
	html = html.replace( re, '#');
	return html;
}




/*
Copyright (c) 2005 JSON.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The Software shall be used for Good, not Evil.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

/*
    The global object JSON contains two methods.

    JSON.stringify(value) takes a JavaScript value and produces a JSON text.
    The value must not be cyclical.

    JSON.parse(text) takes a JSON text and produces a JavaScript value. It will
    return false if there is an error.
*/
var JSON = function () {
    var m = {
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        s = {
            'boolean': function (x) {
                return String(x);
            },
            number: function (x) {
                return isFinite(x) ? String(x) : 'null';
            },
            string: function (x) {
                if (/["\\\x00-\x1f]/.test(x)) {
                    x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
                        var c = m[b];
                        if (c) {
                            return c;
                        }
                        c = b.charCodeAt();
                        return '\\u00' +
                            Math.floor(c / 16).toString(16) +
                            (c % 16).toString(16);
                    });
                }
                return '"' + x + '"';
            },
            object: function (x) {
                if (x) {
                    var a = [], b, f, i, l, v;
                    if (x instanceof Array) {
                        a[0] = '[';
                        l = x.length;
                        for (i = 0; i < l; i += 1) {
                            v = x[i];
                            f = s[typeof v];
                            if (f) {
                                v = f(v);
                                if (typeof v == 'string') {
                                    if (b) {
                                        a[a.length] = ',';
                                    }
                                    a[a.length] = v;
                                    b = true;
                                }
                            }
                        }
                        a[a.length] = ']';
                    } else if (x instanceof Object) {
                        a[0] = '{';
                        for (i in x) {
                            v = x[i];
                            f = s[typeof v];
                            if (f) {
                                v = f(v);
                                if (typeof v == 'string') {
                                    if (b) {
                                        a[a.length] = ',';
                                    }
                                    a.push(s.string(i), ':', v);
                                    b = true;
                                }
                            }
                        }
                        a[a.length] = '}';
                    } else {
                        return;
                    }
                    return a.join('');
                }
                return 'null';
            }
        };
    return {
        copyright: '(c)2005 JSON.org',
        license: 'http://www.crockford.com/JSON/license.html',
/*
    Stringify a JavaScript value, producing a JSON text.
*/
        stringify: function (v) {
            var f = s[typeof v];
            if (f) {
                v = f(v);
                if (typeof v == 'string') {
                    return v;
                }
            }
            return null;
        },
/*
    Parse a JSON text, producing a JavaScript value.
    It returns false if there is a syntax error.
*/
        parse: function (text) {
            try {
                return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
                        text.replace(/"(\\.|[^"\\])*"/g, ''))) &&
                    eval('(' + text + ')');
            } catch (e) {
                return false;
            }
        }
    };
}();
/**********************
	User Videos
***********************/
function fetchProfileVideos(){
	ajax.post( '/api/processors/user',
		{
			type: 'userVideos',
			i : client.getBrowseUserID()
		},
		function (connectionInstance) {
			if(connectionInstance.responseObject){
				if(connectionInstance && connectionInstance.responseObject && connectionInstance.responseObject.error){
					switch( connectionInstance.responseObject.error ){
						case '6675':
								dh.nodes.videosCanvas.obj.innerHTML = '<table class="r o f"><tbody><tr><td height="100%" width="100%" align="center"><img src="/images/perms/carousel.png" /></td></tr></tbody></table>';

								return false;
							break;
					}
				}else{
					client.data.profileVideos = connectionInstance.responseObject;
					displayProfileVideosList();
				}
			}
		} ,
		function (connectionInstance) {

		},
		client.windows.carousel
	);
}

function videoListHTML(){
	var html =	'<div id="videoPool" class="videoPool"></div>';
	return html;
	
}

function videoPlayerListHTML(){
	var html = '<div class="videoList">'+
					'<div class="scrollUp" '+
						'onclick="listDy = 25; moveVList(this.nextSibling.childNodes[0]);" '+
						'onmousedown="this.className=\'scrollUp scrollUpP\';"'+
						'onmouseup="listDy = 0;stopVListMove();this.onmouseover();" '+
						'onmouseout="this.onmouseover();this.className=\'scrollUp\';"'+
						'onmouseover="this.className=\'scrollUp scrollUpH\';"'+
						'></div>'+
					'<div id="videoPlayerList" class="videoListList" '+

					'>'+

						'<div class="videoListCont"></div>'+
					'</div>'+
					'<div class="scrollDown" '+
						'onclick="listDy = -25; moveVList(this.previousSibling.childNodes[0]);" '+
						'onmousedown="this.className=\'scrollDown scrollDownP\';"'+
						'onmouseup="listDy = 0;stopVListMove();this.onmouseover();" '+
						'onmouseout="this.onmouseover();this.className=\'scrollDown\'"'+
						'onmouseover="this.className=\'scrollDown scrollDownH\';"'+
						'></div>'+
				'</div>';
	return html;
}

function videoPlayerAreaHTML(data,index){
	if(!data) data = client.data.profileVideos;
	
	var embed = playerHTML(data,index);
	var html = '<div class="videoPlayerArea">'+
					'<div class="videoPlayer">'+
						'<div id="playerCanvas" class="playerCanvas">'+embed+'</div>'+
						'<div class="codeRateRow">'+
							'<div class="fl">Embed : '+
								'<input class="playerEmbedField" '+
									'value="'+htmlspecialchars_encode(embed)+'" '+
									'style="width:217px" onclick="this.select();"  />'+
							'</div>'+
							'<div id="videoPlayerRater" class="a" style="top: -7px; left : 270px; width: 150px;">'+ratingHTML( data[index],index )+'</div>'+
						'</div>'+
						'<div class="playerBtnRow">'+
							'<div class="vVBtn vcirkVBtn" '+
								'onmouseover="this.className = \'vVBtn vcirkVBtn vcirkVBtnH\'"'+
								'onmousedown="this.className = \'vVBtn vcirkVBtn vcirkVBtnP\'"'+
								'onmouseout="this.className = \'vVBtn vcirkVBtn\'"'+
								'onmouseup="this.onmouseover()"'+
								'onclick="client.openVideo('+data[index].id+','+index+')"'+
							'></div>'+
							'<div class="vVBtn vRCBtn" '+
								'onmouseover="this.className = \'vVBtn vRCBtn vRCBtnH\'"'+
								'onmousedown="this.className = \'vVBtn vRCBtn vRCBtnP\'"'+
								'onmouseout="this.className = \'vVBtn vRCBtn\'"'+
								'onmouseup="this.onmouseover()"'+
								'onclick="reportCopyright('+index+')"'+
							'></div>'+
							'<div class="vVBtn vcomBtn" '+
								'onmouseover="this.className = \'vVBtn vcomBtn vcomBtnH\'"'+
								'onmousedown="this.className = \'vVBtn vcomBtn vcomBtnP\'"'+
								'onmouseout="this.className = \'vVBtn vcomBtn\'"'+
								'onmouseup="this.onmouseover()"'+
								'onclick="addVideoComment('+index+')"'+
							'></div>'+
							'<div class="vVBtn vEmailBtn" '+
								'onmouseover="this.className = \'vVBtn vEmailBtn vEmailBtnH\'"'+
								'onmousedown="this.className = \'vVBtn vEmailBtn vEmailBtnP\'"'+
								'onmouseout="this.className = \'vVBtn vEmailBtn\'"'+
								'onmouseup="this.onmouseover()"'+
								'onclick="openRecommend( {type:\'v\',vid:'+data[index].id+'} )"'+
							'></div>'+
						'</div>'+
					'</div>'+
					'<div id="videoCommentWrap" class="videoCommentWrap">'+videoCommentListHTML(index)+'</div>'+
				'</div>';
	return html;
}

function videoPlayerHTML( data,index ){
	var html =	videoPlayerListHTML()+
				videoPlayerAreaHTML(data,index);
	return html;
}

function videoCommentListHTML(index){
	var html = '';
	var data = client.data.profileVideos;
	var v = data[index];
	var comments = v['comments']
	var limit = comments.length;
	
	for(var x = 0; x < limit; x++){
		html += videoCommentHTML(index,x);
	}
	
	return html;
}

function videoCommentHTML(vI,cI){
		var v = client.data.profileVideos[vI];
		var commObj = v['comments'][cI];
		var html = '<div class="videoCommentNode">'+
						'<div class="videoComMesgRow">'+
							'<div class="vidComAvRow">'+
								'<div class="fl p" onclick="client.browseUser('+commObj.userId+')"><img class="b1sw" src="/api/servlets/images?type=avatar&user_id='+commObj.userId+'&size=41" /></div>'+
								'<div class="fl" style="padding-left:5px;">'+
									'<div class="vidComTABtn" style="width : 100px;">'+
									((client.isHomeProfile())?
										((!commObj.replyId)?
											'<div class="icon16 remarkIcon16 p" style="position : absolute; right : 30px;" onclick="replyVideoComment('+vI+','+cI+')" title="Reply to remark."></div>'+
										'':'')+
											'<div class="icon16 xCircleBlue16 p" style="position : absolute; right : 0px;" onclick="deleteVideoComment('+vI+','+cI+')"  title="Delete this remark."></div>'+
									'':'')+
									'</div>'+
									'<div class="cWhite fl cl" style="width:104px;">'+prepDate(commObj.dateCreated)+'</div>'+
									'<div class="fl cl">'+((commObj.display_name.length  <= 15)?commObj.display_name:commObj.display_name.substr(0,12)+"...")+'</div>'+
								'</div>'+
							'</div>'+
							
							'<div class="vidComMesRow">'+commObj.message+'</div>'+
						'</div>'+
						(
							(commObj.replyId)?
								'<div class="videoComRepRow">'+
									'<div class="vidComRepAvaRow">'+
										'<div class="fl">'+
											client.getBrowseUserObject().profile_info.display_name+
										'</div>'+
										((client.isHomeProfile() && !commObj.reply)?										
										'<div class="icon16 remarkIcon16 p" style="position : absolute; right : 30px;" onclick="editVideoComment('+vI+','+cI+')"  title="Edit your reply."></div>'+
										'<div class="icon16 xCircleBlue16 p" style="position : absolute; right : 0px;" onclick="deleteVideoCommentReply('+vI+','+cI+')"  title="Delete this reply."></div>'+
										'':'')+
									'</div>'+
									'<div class="vidComMesRow">'+
										commObj.replyMessage+
									'</div>'+
								'</div>':
								''
						)+
					'</div>';
		return html;
}

function leaveCommentHTML( index , reply , edit){
	var data = client.data.profileVideos;
	var v = data[index];
	
	if(!edit){
		var save = (isEmpty(reply))? 'saveVideoComment' :'saveVideoCommentReply' ;
		var cancel = (isEmpty(reply))? 'cancelVideoComment' :'cancelVideoCommentReply' ;
	}else{
		var save = 'updateVideoCommentReply' ;
		var cancel = 'cancelUpdateVideoCommentReply';
	}
	
	var html = '<div class="vidComTA">'+
					'<textarea id="addVideoComment'+((!isEmpty(reply))?reply:'')+'" class="fl o f"></textarea>'+
				'</div>'+
				'<div class="vidComTABtn" style="margin-top:4px;">'+
					'<div class="p" onclick="'+save+'('+index+((!isEmpty(reply))? ','+reply:'')+')" title="Send message.">'+
						'<div class="icon16 checkCircleBlue16"></div><div class="fl" style="margin-right:20px;">Send</div>'+
					'</div>'+
					'<div  class="p" class="fl" onclick="'+cancel+'('+index+((!isEmpty(reply))? ','+reply:'')+')"  title="Cancel message.">'+
						'<div class="icon16 xCircleBlue16"></div><div class="fl">Cancel</div>'+
					'</div>'+
				'</div>';
		return html;
}

function cancelVideoComment(index){
	var data = client.data.profileVideos;
	var v = data[index];
	v.comments.shift();
	paintComments(index);
}

function cancelVideoCommentReply(vId,cId){
	var data = client.data.profileVideos;
	var v = data[vId];
	var comObj = v['comments'][cId];
	comObj["replyMessage"] = '';
	comObj["replyId"] = null;
	paintComments(vId);
}

function cancelUpdateVideoCommentReply(vId,cId){
	var data = client.data.profileVideos;
	var v = data[vId];
	var comObj = v['comments'][cId];
	var list= getObject('videoCommentWrap');
	var obj = list.childNodes[cId].childNodes[1].childNodes[1];
	obj.innerHTML =  comObj["replyMessage"];
}

function paintComments(index){
	getObject("videoCommentWrap").innerHTML = videoCommentListHTML(index);
}

function ratingHTML( node , index){
	var rating = node.rating;
	var html =	'<div class="videoNodeRating">'+
						'<div class="rating" style="width:'+rating+'%;"></div>'+
						'<div class="fl fh">'+
							'<div class="ratingHover s1" onclick="rateVideo('+index+',1,this.parentNode.previousSibling)"></div>'+
							'<div class="ratingHover s2" onclick="rateVideo('+index+',2,this.parentNode.previousSibling)"></div>'+
							'<div class="ratingHover s3" onclick="rateVideo('+index+',3,this.parentNode.previousSibling)"></div>'+
							'<div class="ratingHover s4" onclick="rateVideo('+index+',4,this.parentNode.previousSibling)"></div>'+
							'<div class="ratingHover s5" onclick="rateVideo('+index+',5,this.parentNode.previousSibling)"></div>'+
						'</div>'+
					'</div>';
	return html;
}

function videoNodeHTML( node , index){
	var title = (node.title.length > 20)? node.title.substr(0,17)+'...': node.title;
	//var thumbURL = videoThumbnail(node);
		
	var html =	'<div class="videoNode">'+
					'<div class="videoScreenShot" '+
					'onclick="playVideo('+index+')"'+
					'>'+
						'<img src="http://'+videoThumbDomain+'/preview.php?r='+Math.random()+'&t='+node.id+'"/>'+
					'</div>'+
					'<div class="videoNodeTitle cWhite p"  style="text-decoration:underline;" onclick="playVideo('+index+')" title="'+node.title+'">'+title+'</div>'+
					'<div class="videoNodeViews">Views : '+node.views+'</div>'+
						
					'<div class="videoNodePlayBtn playBtn" '+
							'onmouseover="this.className = \'videoNodePlayBtn playBtnHover\'"'+
							'onmousedown="this.className = \'videoNodePlayBtn playBtnPress\'"'+
							'onmouseout="this.className = \'videoNodePlayBtn playBtn\'"'+
							'onmouseup="this.onmouseover()"'+
							'onclick="playVideo('+index+')"'+
					'></div>'+
					ratingHTML(node,index)+
				'</div>';
		return html;
}

function playerHTML( data , index ){
	var videosContent = '';
	var v = data[index];
	
	switch((v.videoStatus)+''){
			case '-2':
				videosContent = "Video Cannot be encoded";
			break;
			case '-1':
				videosContent = "Video Queued";
			break;
			case '0':
				videosContent = "Video Encoding";
			break;
			case '1':
				if(v.embedSrc == '' && v.videoUrl == ''){
					videosContent = createFlash( null, 'http://'+document.domain+'/flash/ecvideo2.swf', 'ecvid', 420, 350, false, 'ecvid=' + v.id, true, true, "TL");
					break;
				}
			default : 
				if( v.embedSrc != '' ){
					videosContent = v.embedSrc;
				}else{
					videosContent = '<a href="'+v.videoUrl+'" style="color:white;" target="_blank">'+v.videoUrl+'</a>';
				}
			break;
	}
	
	return videosContent;
}

function videoNodeListHTML( list ){
	var html = '';
	var limit = list.length;
	for(var x = 0; x < limit; x++){
		html += videoNodeHTML(list[x],x);
	}
	return html;
}

function displayProfileVideosList(){
	dh.nodes.videosCanvas.obj.innerHTML = videoListHTML();
	
	var data = client.data.profileVideos;
	var pool = dh.nodes.videosCanvas.obj.childNodes[0];
	pool.innerHTML = videoNodeListHTML( data );
	vListTop = 0;
	barTop = 0;
	playing = -1;
}

var vPLH = 0;
var vPALH = 0;
var vPALY = 0;
var vListTop = 0;
var playing = -1;
var profilePlayerSwf = null;


var playerListObj = null;
var listDy = 0;
var mvVClock = null;

function playVideo( index ){
	var data = client.data.profileVideos;

	dh.nodes.videosCanvas.obj.innerHTML = videoPlayerHTML( data,index );
	
	var playerWrapper = dh.nodes.videosCanvas.obj.childNodes[1];
	var list = dh.nodes.videosCanvas.obj.childNodes[0].childNodes[1].childNodes[0];
	
	paintVideoPlayerList( list );

	var player = playerWrapper.childNodes[0];
	var comments = playerWrapper.childNodes[1];
	
	profilePlayerSwf = player.childNodes[0];
	var codeRate = player.childNodes[1];
	var btn = player.childNodes[2];
	
	playerListObj = list;
	playing = index;
	viewVideo(playing , list.childNodes[playing].childNodes[2]);
	//try{
		///profilePlayerSwf.childNodes[4].startVideo();
	//}catch(ex){}
}

function startEcVid(){
	var player = getObject("playerCanvas");
	profilePlayerSwf = player.childNodes[0];
	try{
		profilePlayerSwf.startVideo();
	}catch(ex){
		try{
			profilePlayerSwf.childNodes[4].startVideo();
		}catch(ex){}
	}
}

function paintVideoPlayerList( list ){
	var data = client.data.profileVideos;
	list.innerHTML = videoNodeListHTML( data );
	vPLH = getH(list);
	vPALH = getH(list.parentNode);
	vPALY = getAbsY(list.parentNode);
	Y(list,vListTop);
}


function moveVList(){
	clearTimeout(mvVClock);
	
	var newY = (listDy > 0)? (vPALH - 75) : (-1 * (vPALH - 75));
		videoDY = (listDy > 0)? 75 : -75;
	
	var y = vListTop + newY;
	
	if(listDy > 0 && (y) > 0){
		Y(playerListObj,0);
		videoListStop = 0;
		return;
	}else
	if(listDy < 0 && (y) < -(vPLH - vPALH)){
		Y(playerListObj,-(vPLH - vPALH));
		videoListStop = -(vPLH - vPALH);
		return;
	}else{videoListStop = y;}
	
	
	slideVideoList();
	//Y(playerListObj,y);
	//mvVClock = setTimeout(moveVList,33);
	vListTop = videoListStop;
}

var videoListStop = 0;
var videoDY = 25;
function slideVideoList(){
	clearTimeout(mvVClock);
	
	var y = playerListObj.offsetTop + videoDY;
	
	if(listDy > 0 && (y) > videoListStop){
		Y(playerListObj,videoListStop);
		vListTop = videoListStop;
		return;
	}
	if(listDy < 0 && (y) < videoListStop){
		Y(playerListObj,videoListStop);
		vListTop = videoListStop;
		return;
	}
	
	Y(playerListObj,y);
	mvVClock = setTimeout(slideVideoList,33);
	//vListTop = y;
}

function stopVListMove(){
	clearTimeout(mvVClock);
	mvVClock = null;
}

// clear out the Video content on the profile so that the video won't continue playing (audio can still be heard)
function clearProfileVideoContent() {
	var obj = getObject("playerCanvas");
	if(obj)obj.innerHTML = '';
	//dh.nodes.videosCanvas.obj.innerHTML = "";
}

function deleteVideoComment(videoIndex, commentIndex){
	var v = client.data.profileVideos[videoIndex];

	commentAjax({
			type: 'deleteVideoComment',
			vcid: v.comments[commentIndex].videoCommentId,
			uid: client.getBrowseUserID()
		},videoIndex);
}

function addVideoComment(index){
	var data = client.data.profileVideos;
	var v = data[index];
	var videoId = v.id;
	if (videoId < 0 || getObject('addVideoComment') || client.isHomeProfile()){
		return false;
	}

	var b = {	"videoCommentId":'',
				"videoId":videoId,
				"userId":client.loggedInID,
				"message":leaveCommentHTML( index ),
				"dateCreated":"",
				"display_name":client.data.userInfo.profile_info.display_name,
				"replyId":null,
				"replyMessage":null,
				"replyDate":null,
				"avatarName":"1187583326.jpg"
			}

	if(!v.comments || !v.comments.length)
		v.comments = [];
	v.comments.unshift(b);
	getObject("videoCommentWrap").innerHTML = videoCommentListHTML(index);
	getObject("videoCommentWrap").scrollTop = 0;
	getObject('addVideoComment').focus();
}

function replyVideoComment(videoIndex, commentIndex){

	var data = client.data.profileVideos;
	var v = data[videoIndex];
	var comObj = v['comments'][commentIndex];
	var videoId = v.id;
	if (videoId < 0 || getObject('addVideoComment'+commentIndex)){
		return true;
	}

	comObj["replyId"] = 1;
	comObj["replyMessage"] = leaveCommentHTML( videoIndex ,commentIndex);
	comObj["reply"] = 1;

	getObject("videoCommentWrap").innerHTML = videoCommentListHTML(videoIndex);

	getObject('addVideoComment'+commentIndex).focus();
	return true;
}

function saveVideoCommentReply(videoIndex, commentIndex){

	var v = client.data.profileVideos[videoIndex];
	var c = v.comments[commentIndex];

	var vcid = c.videoCommentId;
	var message = getObject('addVideoComment'+commentIndex).value;
	if (isEmpty(message)){
		alert('Please enter a reply message.');
		return false;
	}

	commentAjax({
			type: 'saveVideoCommentReply',
			vcid: vcid,
			message: message,
			uid: client.getBrowseUserID()
		},videoIndex);
}

function saveVideoComment(index){
	var v = client.data.profileVideos[index];
	var videoId = v.id;
	if (videoId < 0){
		return false;
	}

	var message = getObject('addVideoComment').value;
	if (isEmpty(message)){
		alert('Please enter a comment.');
		return false;
	}

	commentAjax({
			type: 'saveVideoComment',
			videoId: videoId,
			msg: message,
			uid: client.getBrowseUserID()
		},index);
}

function rateVideo(index,rate,obj){
	var data = client.data.profileVideos;
	var v = client.data.profileVideos[index];
	var videoId = v.id;
	ajax.post('/api/processors/rating',
		{type:'r',v:videoId,r:rate},
		function (connectionInstance) {
			if(connectionInstance.responseObject){
				obj.style.width = connectionInstance.responseObject.rating + "%";
				v.rating = connectionInstance.responseObject.rating;
				if(getObject('videoPlayerList')){
					var list = dh.nodes.videosCanvas.obj.childNodes[0].childNodes[1].childNodes[0];
					paintVideoPlayerList( list );
					getObject("videoPlayerRater").innerHTML = ratingHTML( data[playing],playing );
				}
			}
		} ,
		function (connectionInstance) {

		}
	)
}

function deleteVideoCommentReply(videoIndex, commentIndex){
	var v = client.data.profileVideos[videoIndex];
	var c = v.comments[commentIndex];

	commentAjax({
			type: 'deleteVideoCommentReply',
			vcid: c.replyId,
			uid: client.getBrowseUserID()
		},videoIndex);
}

function editVideoComment(videoIndex, commentIndex){
	var data = client.data.profileVideos;
	var v = data[videoIndex];
	var comObj = v['comments'][commentIndex];
	var videoId = v.id;
	if (videoId < 0 || getObject('addVideoComment'+commentIndex)){
		return true;
	}
	var list= getObject('videoCommentWrap');
	var obj = list.childNodes[commentIndex].childNodes[1].childNodes[1];

	obj.innerHTML =  leaveCommentHTML( videoIndex ,commentIndex,"er" );
	var ta = getObject('addVideoComment'+commentIndex);
	ta.value = comObj["replyMessage"];
	ta.focus();
	return true;
}

function updateVideoCommentReply(videoIndex, commentIndex){

	var v = client.data.profileVideos[videoIndex];
	var c = v.comments[commentIndex];

	var message = getObject('addVideoComment'+commentIndex).value;
	if (isEmpty(message)){
		alert('Please enter a comment.');
		return false;
	}

	commentAjax({
			type: 'editVideoCommentReply',
			vcid: c.replyId,
			message: message,
			uid: client.getBrowseUserID()
		},videoIndex);
}
function commentAjax(data,videoIndex){
	ajax.post( '/api/processors/user',
		data,
		function (connectionInstance) {
			if(connectionInstance.serverResponse != 'false'){
				client.data.profileVideos[videoIndex].comments = connectionInstance.responseObject;
				paintComments(videoIndex);
			}
		} ,
		function (connectionInstance) {

		},
		client.windows.carousel
	);
}

function viewVideo(index,obj){
	var data = client.data.profileVideos;
	var v = client.data.profileVideos[index];
	var vId = v.id;
	ajax.post('/api/processors/views',
		{type:'vV',v:vId},
		function (connectionInstance) {
			if(connectionInstance.serverResponse != 'false'){
				obj.innerHTML = 'Views : '+connectionInstance.serverResponse;
				v.views = connectionInstance.serverResponse;
			}
		} ,
		function (connectionInstance) {

		}
	);
}

function resetProfilePlayerSwf(){
	if(profilePlayerSwf)profilePlayerSwf.style.left = "0px";
}

function reportCopyright(index){
	var data = client.data.profileVideos;
	var v = client.data.profileVideos[index];
	var vId = v.id;
	if(profilePlayerSwf)profilePlayerSwf.style.left = "1000px";
	ajax.post('/api/processors/cpr',
		{type:'r',v:vId},
		function (connectionInstance) {
			if(connectionInstance.responseObject){
				switch(connectionInstance.responseObject.result){
					case "error" : 
						client.userError("Copyright",connectionInstance.responseObject.msg,resetProfilePlayerSwf);
						break;
					case "success" : 
						client.userNotice("Copyright","Your report has been sent to our media moderators.<br />Thank you for helping to keep eCirkit a media piracy free environment",resetProfilePlayerSwf);
						break;
				}
			}else{
				client.userError("Copyright","There has been an error sending your report, please try again.",resetProfilePlayerSwf);
			}
		} ,
		function (connectionInstance) {
			resetProfilePlayerSwf();
		}
	)
}
	function window_announceResize(){
		//dont resize peices if we're minimized
		if(client.windows.announce.windowState == windowState.minimized) return;

		var selectedTabKey = client.windows.announce.selectedTab.id;

		if(selectedTabKey){
			var workingContent =  client.windows.announce.selectedTab.canvas;
			workingContent.moveTo( client.windowXPadding,  client.windowYPadding);
			workingContent.resizeTo( client.windows.announce.canvas.w - (client.windowXPadding * 2),  client.windows.announce.canvas.h - (client.windowYPadding * 2));
			switch(selectedTabKey){
				case 'annInbox':
					dh.nodes.annInboxContent.resizeTo( workingContent.w - dh.nodes.annInboxList.w , workingContent.h);
					break;
				case 'annOutbox':
					dh.nodes.annOutboxContent.resizeTo( workingContent.w - dh.nodes.annOutboxList.w , workingContent.h);
					break;
				case 'annCompose':
					break;
			}
		}
	}

	function window_announceTab(){
		client.data.selectedAnnouncement = '';

		switch(client.windows.announce.selectedTab.id){
			case 'annInbox':
				client.data.announcements = '';
				client.data.announcementType = 'received';
				fetchAnnouncements('receivedAnnouncements');
				break;
			case 'annOutbox':
				client.data.announcements = '';
				client.data.announcementType = 'sent';
				fetchAnnouncements('sentAnnouncements');
				break;
			case 'annCompose':
				composeAnnouncement();
				break;
		}
	}

	function fetchAnnouncements(type){
		ajax.post( '/api/processors/messaging',
			{
				type: type
			},
			function (connectionInstance){
				if (connectionInstance.responseObject){
					client.data.announcements = connectionInstance.responseObject;
					displayAnnouncementList();
				}
				return true;
			},
			function (connectionInstance){

			},
			client.windows.announce
		);
	}

	function displayAnnouncementList(){
		var content = '';
		var a = '';
		for (var i = 0; i < client.data.announcements.length; i ++){
			a = client.data.announcements[i];
			content += 	'<div id="announcement_' + i + '" class="p announcementSubjectWrapper"  onclick="displayAnnouncementContent(' + i + ')">' +
							'<div id="announcementSubject_' + i + '" class="announcementSubject gtm">' + a.subject + '</div>' +
							'<div id="announcementDate_' + i + '" class="announcementDateCreated gtxs">' +	formatDateTime(a.dateCreated) + '</div>' +
						'</div>';
		}

		if (client.data.announcementType == 'received'){
			dh.nodes.annOutboxList.purge();
			dh.nodes.annInboxList.write(content);
		}else if (client.data.announcementType == 'sent'){
			dh.nodes.annInboxList.purge();
			dh.nodes.annOutboxList.write(content);
		}

		// display the first announcement if none was selected before
		if (isEmpty(client.data.selectedAnnouncement)){	client.data.selectedAnnouncement = 0; }
		displayAnnouncementContent(client.data.selectedAnnouncement);
	}

	function displayAnnouncementContent(index){
		var a = client.data.announcements[index];

		announcementSetSelected(index);

		var controls = '<a class="p actionLabel" onclick="deleteAnnouncement(' + index + ');">DELETE</a>';

		if (client.data.announcementType == 'received'){
			controls += '&nbsp;&nbsp;&nbsp;<a class="p actionLabel" onclick="composeAnnouncement(' + index + ');">REPLY</a>';
		}

		var data = '';
		data += '<div id="" class="annTopWrapper">' +
					'<div id="" class="annContentTitle">' + a.subject + '</div>' +
					'<div id="" class="annControls">' + controls + '</div>' +
				'</div>' +
				'<div id="" class="annContentWrapper">' +
				 ((client.data.announcementType == 'received')? '<div id="annAvatar_' + index + '" class="annAvatar"></div>' : '')  +
					'<div id="" class="annContent">' + a.message + '</div>' +
				'</div>';

		if (client.data.announcementType == 'received'){
			dh.nodes.annOutboxContent.purge();
			dh.nodes.annInboxContent.write(data);

			var avatarInfo = {fileName: a.avatarName, userName: a.displayName, user_id: a.fromUserId};
			displayUserAvatar(getObject('annAvatar_' + index), avatarInfo, true, true, false );

		}else if (client.data.announcementType == 'sent'){
			dh.nodes.annInboxContent.purge();
			dh.nodes.annOutboxContent.write(data);
		}

	}


	function announcementSetSelected(index){

		if (!isEmpty(client.data.selectedAnnouncement) && parseInt(client.data.selectedAnnouncement) >= 0){
			var selected = getObject("announcement_" + client.data.selectedAnnouncement);
			var tmpClass = selected.className;
			tmpClass = tmpClass.replace("selected", "");
			selected.className = tmpClass;
		}

		var e = getObject("announcement_" + index);
		e.className += ' selected ';
		client.data.selectedAnnouncement = index;
	}

	function deleteAnnouncement(index){
		var a = client.data.announcements[index];

		ajax.post('/api/processors/messaging',
			{
				type: 'deleteAnnouncement',
				id: a.announcementId
			},
			function (connectionInstance){
				if (connectionInstance.serverResponse == 'ok'){
					removeAnnouncementFromList(index);
				}
			},
			function (connectionInstance){

			}
		);
	}

	function removeAnnouncementFromList(index){
		index = parseInt(index);

		if (client.data.announcementType == 'received'){
			dh.nodes.annInboxContent.purge();
			var c = getObject('announcement_' + index);
			dh.nodes.annInboxList.obj.removeChild(c);

		}else if (client.data.announcementType == 'sent'){
			dh.nodes.annOutboxContent.purge();
			var c = getObject('announcement_' + index);
			dh.nodes.annOutboxList.obj.removeChild(c);
		}

		// reset our selected announcement index
		client.data.selectedAnnouncement = null;

		// select the previous announcement in list
		if ((index-1) == 0){
			displayAnnouncementContent(0);
			announcementSetSelected(0);
		}else if ((index-1) < 0){
			displayAnnouncementContent(1);
			announcementSetSelected(1);
		}else{
			displayAnnouncementContent(index-1);
			announcementSetSelected(index-1);
		}
	}

	function composeAnnouncement(index){

		var message = '';
		if (index >= 0){
			var a = client.data.announcements[index];
			message = '<br /><hr />----- Original Announcement -----<br />';
			message += 'From: ' + a.displayName + '<br />';
			message += 'Sent: ' + a.dateCreated + '<br />';
			message += 'Subject: ' + a.subject + '<br />';
			message += '<br />' + a.message;
			client.windows.announce.__tab('annCompose');
		}

		var content = '';
		content += 	'<table width="100%" cellpadding="5" border="0">' +
					  '<tr height="25">' +
					    '<td align="right" valign="middle">Subject:</td>' +
					    '<td valign="top"><div id="subjectWrapper" class="inputBoxWrapper"><input type="text" size="64" maxlength="64" name="subject" id="composeAnnouncementSubject" /></div></td>' +
					  '</tr>' +
					  '<tr>' +
					    '<td align="right" valign="top">Message:</td>' +
					    '<td valign="top">' +
					      '<textarea name="composeAnnouncementMessage" style="width: 100%;" rows="25">' + message + '</textarea>' +
					    '</td>' +
					  '</tr>' +
					  '<tr>' +
					  	'<td>&nbsp;</td>' +
					  	'<td><a class="actionLabel" onclick="' + ((index >= 0)? 'replyToAnnouncement(' + index + ')' : 'sendAnnouncement()') + ';">SEND</a>&nbsp;&nbsp;&nbsp;<a class="actionLabel" onclick="client.windows.announce.__tab(\'annInbox\');">CANCEL</a></td>' +
					  '</tr>' +
					'</table>';

		dh.nodes.annComposeCanvas.write(content);

		var fck = new FCKeditor( 'composeAnnouncementMessage' );
		fck.BasePath = "/tools/fck/";
		fck.ToolbarSet = 'Forum';
		fck.ReplaceTextarea();
	}

	function sendAnnouncement (){
		var subject = getObject('composeAnnouncementSubject').value;
		if (subject.length <= 0){
			subject = "(no subject)";
		}

		var message = getFckContents('composeAnnouncementMessage');
		if (message.length <= 1){
			alert('Please enter a message.');
			return false;
		}

		alert('Announcement sent successfully.');

		ajax.post('/api/processors/messaging',
			{
				type: 'sendAnnouncement',
				subject: subject,
				message: message
			},

			function (connectionInstance){
				if (connectionInstance.serverResponse == 'ok'){
					client.windows.announce.__tab('annInbox');
				}
				return true;
			},

			function (connectionInstance){

			}
		);
	}

	function replyToAnnouncement(index){

		if (index < 0){
			alert('Could not locate the announcement you wish to reply to.');
			return false;
		}

		var toUser = client.data.announcements[index].fromUserId;
		if (toUser <= 0){
			alert('Could not locate the user to send the reply to. Please try again.');
			return false;
		}

		var subject = getObject('composeAnnouncementSubject').value;
		if (subject.length <= 0){
			subject = "(no subject)";
		}

		var message = getFckContents('composeAnnouncementMessage');
		if (message.length <= 1){
			alert('Please enter a message.');
			return false;
		}

		ajax.post('/api/processors/messaging',
			{
				type: 'sendEmail',
				subject: subject,
				message: message,
				userId: toUser
			},

			function (connectionInstance){
				if (connectionInstance.serverResponse == 'ok'){
					client.windows.announce.__tab('annInbox');
					alert('Your reply was sent successfully');
				}
				return true;
			},

			function (connectionInstance){

			}
		);

	}
	/*************************************************

	* 		Profile Rss Window

	*************************************************/
	function initProfileRss(){

		if(!client.data.profileRssFeeds){

			dh.nodes.profileRssCanvas.purge();

			ajax.post( '/api/processors/rss',
				{
					type: 'getProfileFeeds',
					i:client.getBrowseUserID()
				},
				function (connectionInstance){
					if(connectionInstance && connectionInstance.responseObject && connectionInstance.responseObject.error){
						switch( connectionInstance.responseObject.error ){
							case '6675':
									getObject('profileRssCanvas').innerHTML = '<table height="100%" width="100%"><tbody><tr><td height="100%" width="100%" align="center"><img src="/images/perms/windshield.png"  width="100%" /></td></tr></tbody></table>';
									return false;
								break;
						}
					}else if (connectionInstance.responseObject.length > 0){
							client.data.profileRssFeeds = connectionInstance.responseObject;
							setTimeout( displayProfileRss , 0); //new thread, new stack
					}
					return true;
				},
				function (connectionInstance){

				},
				client.windows.windshield
			);
		}else{
			//already built
		}
	}

	function displayProfileRss(){
		var rssCanvas = getObject("profileRssCanvas");

		for(feedId in client.data.profileRssFeeds){
			f = client.data.profileRssFeeds[feedId];
			var feed = createObject("div",'','profileRssFeed',rssCanvas,'');

			var feedTitle = createObject("div",'','profileRssFeedTitle',feed,'');
				var	postToggle = createObject('div','feedToggle_'+feedId,'fl rssToggle p',feedTitle,"");
					postToggle.onclick = Function("showFeedPosts("+feedId+")");
					createObject("div",'','fl rssTitle',feedTitle,'<img height="16" width="16" src="' + f.favicon + '">&nbsp;'+f.feed_title);//'<img src="'+f.feed_image+'" />'

			var postList = dh.createDHObject("div",'feed_'+feedId,'profileRssFeedList',feed,'',hidden).obj;
			for(postId in f.items){
				var p = f.items[postId];
				var post = createObject('div','','profileRssPost',postList,'');

				var postTitle = createObject('div','','profileRssPostTitle',post,'');
					var	descToggle = createObject('div','postToggle_'+feedId+'_'+postId,'fl rssToggle p',postTitle,"");
						descToggle.onclick = Function("showPostDescription("+feedId+","+postId+");");
					var story = createObject('div','','fl rssTitle p',postTitle,'<div style="text-decoration:underline;">' + p.title + '</div>');
						story.style.width = "80%";
						prepStory(story , p.link , p.title, f.feed_title);
				var description = dh.createDHObject('div','postDesc_'+feedId+'_'+postId,'profileRssPostDescription',post,p.description,hidden).obj;
			}
		}
	}

	function prepStory(story , link , title, feed){
		//story.firstChild.onmouseover = function(){descriptionPop(title); }
		story.firstChild.onclick = function(){loadInBrowser({Url:link,title:feed,description:title});}
	}
	function showFeedPosts( feedId ){
		var feed = dh.$('feed_'+feedId);
		var toggle = getObject('feedToggle_'+feedId);
		if(feed.visible){
			toggle.style.backgroundImage =  "url(" + ecirkitImagesURL + "tree_collapsed.png)";
			feed.hide();
		}else{
			toggle.style.backgroundImage =  "url(" + ecirkitImagesURL + "tree_expanded.png)";
			feed.show();
		}
	}

	function showPostDescription(feedId, postId){
		var post = dh.$('postDesc_'+feedId+'_'+postId);
		var toggle = getObject('postToggle_'+feedId+'_'+postId);
		if(post.visible){
			toggle.style.backgroundImage =  "url(" + ecirkitImagesURL + "tree_collapsed.png)";
			post.hide();
		}else{
			toggle.style.backgroundImage =  "url(" + ecirkitImagesURL + "tree_expanded.png)";
			post.show();
		}
	}


function initLogin(){
	if(!client.windows.login){
		//---------------------------
		//News Pane
		//---------------------------
		client.addWindow( 'login',
			{
				startingState:	windowState.minimized,
				centerOnShow:	true,
				alwaysOnTop:	true,
				resizable:		false,
				closeButton:	true,
				maximizeButton: false,
				minimizeButton: false,
				shadeButton:	false,
				showTabs:		false,
				showStatus:		true,
				showIcon:		false
			},
			dh.nodes.windowspace.obj,
			"Log In"
		);
		client.windows.login.setCanvas( dh.nodes.loginCanvas );
		client.windows.login.minimizeTo = dh.nodes.mini_login ;
		client.windows.login.onClose = function () {
			//if we're closing and it's not logged in then we closed it
			//only because we don;t track failures here yet.
			//that would be if we counted attempts and login_logout can send a 'failure' action
			client.closeMatte();
			//client.login_logout();
			client.windows.login.minimize();

			if( !client.isLoggedIn() ) client.loginResponse( 'cancel' );

			return true;
		};

		//listen for the enter key in the login form as a whole.
		dh.nodes.loginCanvas.obj.onkeydown =
			function (e) {
				if(!e) e = window.event;
				if( (e.keyCode || e.which) == 13) {
					login();
				}
			};

	}

}

function login(){
	//save in autocompelte
	getObject('loginForm').submit();

	var username = getObject("loginUserName").value;
	if (isEmpty(username)) {
		alert('Invalid username');
		return false;
	}

	var pass = getObject("loginPass").value;
	if (isEmpty(pass)){
		alert('Please enter password.');
		return false;
	}

	var rememberMe = getObject("rememberMe");
	if (rememberMe.checked){
		rememberMe = 'true';
	}else{
		rememberMe = 'false';
	}

	var seed = '';
	// get the seed first
	ajax.post('/api/processors/login',
		{
			a: 's'
		},

		function (connectionInstance){

			// we got the seed, lets attempt to log in
			var seed = connectionInstance.serverResponse;
			ajax.post('/api/processors/login',
				{
					a: 'login',
					hash: hex_sha1(hex_sha1(pass) + seed),
					s: seed,
					user: username,
					rme: rememberMe
				},

				function (connectionInstance){
					if(connectionInstance.responseObject){

						//client.windows.login.minimize();

						//client.userNotice("Log In", "You have logged in successfully, welcome back to eCirkit.com.");

						client.data["userInfo"] = connectionInstance.responseObject;
						client.loggedInID = client.data["userInfo"].profile_info.user_id;
						client.login_logout();

					}else if (connectionInstance.serverResponse == 'false'){
						client.userError("Log In", "Invalid username and/or password.");
					}else{
						client.userError("Log In", connectionInstance.serverResponse);
					}
					return true;
				},

				function (connectionInstance){
					client.userError("Log In", "Login request failed, please try again.");
				},
				client.windows.login
			);
			return true;
		},

		function (connectionInstance){
			client.userError("Log In", "Login key request failed. Please try again.");
		},
		client.windows.login
	);

}

function logout(){

	ajax.post('/api/processors/login',
		{
			a: 'logout'
		},

		function (connectionInstance){
			//client.userNotice("Log out", "You have been logged out of eCirkit.com successfully.");
			deleteCookie("ecsid", "/");
			// delete remember me cookie
			// this is the only time this gets deleted
			deleteCookie("ecrme", "/");
			client.loggedInID = -1;
			delete client.data['userInfo'];
			client.login_logout();
			window.onbeforeunload = null;
			splash();
			return true;
		},
		function (connectionInstance){
			client.userError("Log out", "Log out request failed. Please try again.");
		}
	);

}
var inviteForm = null;
function openInvite(  ) {
	if(profilePlayerSwf)profilePlayerSwf.style.left = "2000px";
	client.showWorkspaceMatte(dhNull, false, closeInvite);
    if (!dh.nodes.inviteForm) {
        showBlock(getObject("inviteForm"));
        dh.addObject("inviteForm", alwaysOnTop + centerViewport + hidden);
    }
   getObject("inviteFormStatus").innerHTML =	'<div class="inviteFormBodyBorder inviteFormBodyBorderLeft"></div>'+
												'<div class="inviteFormBodyBorder inviteFormBodyBorderRight"></div>'+
												'<div id="email_inv_icon" class="a statusIcon"></div>'+
												'<div id="email_inv_label" class="a"></div>';

	if(inviteForm){
		inviteForm.empty();
	}else{
		inviteForm = new eFormit();
	}
	
	inviteForm.parseForm(getObject("inviteFormBody"));
	
    dh.nodes.inviteForm.show();
    dh.nodes.inviteForm.bringToFront();
	getObject('invite_email_0').focus();
}

function closeInvite() {
	if(profilePlayerSwf)profilePlayerSwf.style.left = "0px";
    dh.nodes.inviteForm.hide();
	getObject("inviteFormBody").innerHTML = '<div class="inviteFormBodyBorder inviteFormBodyBorderLeft"></div>'+
					'<div class="inviteFormBodyBorder inviteFormBodyBorderRight"></div>'+
					'<div class="inviteFormWrapper ">'+
						'<div class="inviteFormInput"><input id="invite_email_0" name="invite_email_0" type="text" onkeyup="resetActivityField(\'invite_email_0\',650,testInvEmail,this);" /></div>'+
					'</div>';
    return true;
}

function sendInvites(){
	if(!(inviteForm && inviteForm.elements))return false;
	
	for(key in inviteForm.elements){
		if(!inviteForm.elements[key].obj.valid && inviteForm.elements[key].obj.value != ''){
			alert("Please Enter A Vaild Email Address or Clear the Text Field.");
			inviteForm.elements[key].obj.focus();
			return false;
			//client.userError("Invalid Email","Please Enter A Vaild Email Address or Clear the Text Field.",function(){inviteForm.elements[key].obj.focus();})
		}
	}
	var data = inviteForm.getJSON();
	for(key in data){
		if(data[key] == '')delete data[key];
	}
	
	//console.log(data);
	ajax.post(	"/api/invite",
				data,
				function(conn){
					client.userNotice(	"Thank You!",
										"Your invitations have been mailed. Thank you for supporting eCirkit.",
										function(){client.closeMatte();}
									);
				}
	);
}

var recDat;
function openRecommend( data ) {
    if(profilePlayerSwf)profilePlayerSwf.style.left = "2000px";
	client.showWorkspaceMatte(dhNull, false, closeRecommend);
    if (!dh.nodes.registrationForm) {
        showBlock(getObject("recommendForm"));
        dh.addObject("recommendForm", alwaysOnTop + centerViewport + hidden);
    }

	recDat = data;
    dh.nodes.recommendForm.show();
    dh.nodes.recommendForm.bringToFront();
	getObject('rec_email').focus();
}

function closeRecommend() {
	if(profilePlayerSwf)profilePlayerSwf.style.left = "0px";
    dh.nodes.recommendForm.hide();
    return true;
}

var recommending = false;
function recommend(){
	if(recommending)return;
	recommending = true;
	var email = getObject('rec_email');

	if( !email ) return; //some sort of bizarre error would cause this

	if(!email.valid){
		email.focus();
		email.select();
		return;
	}

	recDat.email = email.value;
	ajax.post('/api/processors/recommend',
		recDat,
		function ( connectionInstance ) {
			closeRecommend();
			if(connectionInstance.serverResponse == 'limit' ){
				client.userError('Failure to Send','You have reached your limit of recommendations for this hour. Please try again in 60 minutes.');
			}else if(connectionInstance.serverResponse == 'false' ){
				client.userError('Failure to Send','There was an error in sending your recommendation');
			}else{
				 var ep = new ePromptIt( 'Recommendation Sent', "Your recommendation has been sent to the requested e-mail address.", null, promptButtons.ok , promptThemes.notice,2500);
			}
			recommending = false;
			return true;
		},
		function ( connectionInstance ) {	recommending = false;	}
		)
	return false;
}

function openRegister() {
    client.showWorkspaceMatte(dhNull, false, closeRegister);
	if(profilePlayerSwf)profilePlayerSwf.style.left = "2000px";
    if (!dh.nodes.registrationForm) {
        showBlock(getObject("registrationForm"));
        dh.addObject("registrationForm", alwaysOnTop + centerViewport + hidden);
    }
    dh.nodes.registrationForm.show();
    dh.nodes.registrationForm.bringToFront();
}

function closeRegister() {
	if(profilePlayerSwf)profilePlayerSwf.style.left = "0px";
    dh.nodes.registrationForm.hide();
    return true;
}

function register(){
	var email = getObject('reg_email');
	var pass = getObject('reg_pass');
	var cpass = getObject('reg_cpass');
	var tos = getObject('reg_tos');

	if( !email || !pass || !cpass ) return; //some sort of bizarre error would cause this

	if(!email.valid){
		email.focus();
		email.select();
		return;
	}

	if(!cpass.valid){
		cpass.focus();
		cpass.select();
		return;
	}

	if( isEmpty(email.value) ){
		setFieldStatus(email, 'above', 'error', 'No email address specified.');
		return;
	}

	if( trim(pass.value) == "" || trim(cpass.value) == "" ){
		setFieldStatus(cpass, 'below', 'error', 'Please confirm your password.');
		return;
	}

	if(pass.value != cpass.value ){
		setFieldStatus(cpass, 'below', 'error', 'Passwords do not match');
		return;
	}

	if( !tos.checked ){
		client.userError('Registration Error', "You must agree to the terms of service and verify your age to continue.")
		return;
	}

	ajax.post('/api/processors/registration',
	{
		action : 'register',
		email : email.value,
		password : hex_sha1(cpass.value)
		},
		function ( connectionInstance ) {
			if( connectionInstance.serverResponse != 'false' ) {
				window.newUserID = parseInt(connectionInstance.serverResponse);
				closeRegister();
				 var ep = new ePromptIt( 'Registration Complete', "Your account has been created and you are now logged in. Would you like to go to your webtop now?", registerCallback, promptButtons.yesNo , promptThemes.notice);
			} else {
				/*
				getObject('registrationFormError').innerHTML = connectionInstance.serverResponse
				*/
				alert('reg failed.');
			}
			return true;
		},
		function ( connectionInstance ) {		}
		)
	return false;
}

function registerCallback(response) {
    if (response == "Yes") {
        window.location.href = "/user/" + window.newUserID + "?layer=webtop";
    }
}

	/*
	 * elementsToColor may be a single object
	 */
	function fieldValidatior(fieldName, elementsToColor , iconNode, labelNode , noAjax){

		setFieldStatus(elementsToColor , iconNode, labelNode, 'loading', 'checking...');

		if(noAjax){
			if(elementsToColor.value.match(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/)){
				setFieldStatus( elementsToColor , iconNode, labelNode, 'ok');
				return true;
			}else{
				setFieldStatus( elementsToColor , iconNode, labelNode,  'error', 'Invalid E-mail.');
				return false;
			}
		}else{
			ajax.post('/api/processors/registration',
				{
					action : 'testField',
					field: fieldName,
					value : elementsToColor.value
				},
				function( connectionInstance ) {
					if(connectionInstance.serverResponse == 'ok'){
						setFieldStatus( elementsToColor , iconNode, labelNode, 'ok');
					} else {
						setFieldStatus( elementsToColor , iconNode, labelNode,  'error', connectionInstance.serverResponse);
					}
				},
				function( connectionInstance ) {
					//setFieldStatus(srcElement , 'error', 'Unknown error.');
				}
			);
		}
	}

	function setFieldStatus( elementsToColor , iconNode, labelNode, status, labelText){

		var bgColor = "";
		var labelClass = "";
		var iconClass = "";
		var valid = false;

		switch(status){
			case 'loading':
				iconClass = 'a statusIcon statusLoading';
				labelText = "checking..."
				labelClass = 'a gtm';
				break;
			case 'ok':
				iconClass = 'a statusIcon statusOk';
				labelText = "OK";
				labelClass = 'a clG gtm b'
				bgColor = '#d9ffd9';
				valid = true;
				break;
			case 'error':
				iconClass = 'a statusIcon statusError';
				labelClass = 'a clR gtm b'
				bgColor = '#ffd9d9';
				break;
		}

		if( isArray(elementsToColor) ){
			for( var elemID in elementsToColor ){
				var elem = elementsToColor[elemID];
				elem.style.backgroundColor = bgColor;
				elem.valid = valid;
			}
		} else {
			elementsToColor.style.backgroundColor = bgColor;
			elementsToColor.valid = valid;
		}

		if(iconNode){
			iconNode.className = iconClass;
			showObject(iconNode);
		}

		if(labelNode){
			labelNode.className = labelClass;
			if(labelText){
				labelNode.innerHTML = labelText;
			}
			showObject(labelNode);
		}


	}

	//form field testing functions
	function testEmail(){
		//function fieldValidatior(fieldName, elementsToColor , iconNode, labelNode){

		 fieldValidatior( 'email', getObject('reg_email'), getObject('email_icon'),  getObject('email_label') );
	}

	//form field testing functions
	function testRecEmail(){
		//function fieldValidatior(fieldName, elementsToColor , iconNode, labelNode){

		 fieldValidatior( 'email', getObject('rec_email'), getObject('email_rec_icon'),  getObject('email_rec_label') , true );
	}

	function testInvEmail( field ){
		if(fieldValidatior( 'email', field, getObject('email_inv_icon'),  getObject('email_inv_label') , true )){
			var num = parseInt(field.id.replace(/invite_email_(.*)/,'$1')) + 1
			if(!field.good){
				var obj = createObject("div","","inviteFormWrapper",getObject("inviteFormBody"),
						'<div class="inviteFormInput"><input id="invite_email_'+num+'" name="invite_email_'+num+'" type="text" onkeyup="resetActivityField(\'invite_email_'+num+'\',650,testInvEmail,this);" /></div>');
				field.good = true;
				obj = obj.childNodes[0].childNodes[0];
				if(!inviteForm){
					inviteForm = new eFormit();
					inviteForm.parseForm(getObject("inviteFormBody"));
				}else{
					inviteForm.addElement(obj, "text", '');
				}
				obj.focus();
			}else{
				getObject("invite_email_"+num).focus();
			}
		}else if(field.value == ''){
			field.style.background = 'none';
			getObject("email_inv_icon").className = "a statusIcon";
			getObject("email_inv_label").innerHTML = '';
		}
	}

	function testPasswords(){
		var p = getObject('reg_pass');
		var cp = getObject('reg_cpass');

		var elements = [];
		elements[0] = p;
		elements[1] = cp;

		//function setFieldStatus( elementsToColor , iconNode, labelNode, status, labelText)

		if( trim(p.value) == "" ){
			setFieldStatus( [p,cp] , getObject('pass_icon'), getObject('pass_label'), 'error', 'You must enter a password.')
			return;
		}

		if( trim(cp.value) == "" ){
			setFieldStatus( [p,cp] , getObject('pass_icon'), getObject('pass_label'), 'error', 'You must confirm your password.')
			return;
		}

		if(p.value != cp.value) {
			setFieldStatus( [p,cp] , getObject('pass_icon'), getObject('pass_label'), 'error', 'Passwords do not match.')
			return;
		}

		setFieldStatus( [p,cp] , getObject('pass_icon'), getObject('pass_label'), 'ok')
	}

	function testTos (){
		var t = getObject('reg_tos');

		if( t.checked == false ){
			setFieldStatus( t , getObject('tos_icon'), getObject('tos_label'), 'error', 'You must agree to the terms of service.')
			return;
		} else {
			setFieldStatus( t , getObject('tos_icon'), getObject('tos_label'), 'ok')
		}
	}
	function popUp(URL) {
		day = new Date();
		id = day.getTime();
		eval("page" + id + " = window.open(URL, '" + id + "', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=0,width=325,height=300,left = 690,top = 375');");
	}
	var client;
	var canvasStorage;
	var remoteIFrame;
	//scrolling callback - fixed position fix
	function scrollViewport(){ dh.nodes.header.animate( new dh.tweenDetails( 0, 0, dhNull, dhNull, 100, 1, 20 ), function(){} ); }

	//function uninit(e){
	//	var res = 'This action will leave eCirkit. Are you sure you want to continue?';
	//
	//	return res;
	//}
	var cntrl = false;
	var alt = false;
	var shift = false;
	function init(){
		dhInit();

		client = new ClientObject();
		ajax = new Ajax();
		remoteIFrame = getObject("remoteIFrame");
		remoteIFrame.onload = function(){client.remoteCallback();};
		//document.onkeydown = hotKeysDown;
		//document.onkeyup = hotKeysUp;
		//dh.onGrab = client.highlightDropZones;
		//dh.onDrop = client.dimDropZones;
		//client.userInfo();

		dh.addObject("header", 				alwaysOnTop);
			client.addHelpBeacon( 'community', dh.addObject("menu_myMail", 	none).obj, "menu_myMail");
			client.addHelpBeacon( 'community', dh.addObject("menu_browse", 	none).obj, "menu_browse");
			client.addHelpBeacon( 'community', dh.addObject("menu_extractor", 	none).obj, "menu_extractor");
			client.addHelpBeacon( 'community', dh.addObject("menu_myRss", 	none).obj, "menu_myRss");
			client.addHelpBeacon( 'community', dh.addObject("menu_snapBrowser", 	none).obj, "menu_snapBrowser");
			client.addHelpBeacon( 'community', dh.addObject("menu_myVideos", 	none).obj, "menu_myVideos");
			client.addHelpBeacon( 'community', dh.addObject("menu_myPhotos", 	none).obj, "menu_myPhotos");
			client.addHelpBeacon( 'community', dh.addObject("menu_myBlogs", 	none).obj, "menu_myBlogs");
			client.addHelpBeacon( 'community', dh.addObject("menu_vault", 	none).obj, "menu_vault");
			client.addHelpBeacon( 'community', dh.addObject("menu_myForSale", 	none).obj, "menu_myForSale");
			client.addHelpBeacon( 'community', dh.addObject("menu_myContacts", 	none).obj, "menu_myContacts");
			client.addHelpBeacon( 'community', dh.addObject("menu_buddylist", 	none).obj, "menu_buddylist");
			client.addHelpBeacon( 'community', dh.addObject("menu_forums", 	none).obj, "menu_forums");
			client.addHelpBeacon( 'community', dh.addObject("menu_mySettings", 	none).obj, "menu_mySettings");

		client.addHelpBeacon( 'webtop', dh.$("menu_myMail").obj, "menu_myMail");
		client.addHelpBeacon( 'webtop', dh.$("menu_browse").obj, "menu_browse");
		client.addHelpBeacon( 'webtop', dh.$("menu_extractor").obj, "menu_extractor");
		client.addHelpBeacon( 'webtop', dh.$("menu_myRss").obj, "menu_myRss");
		client.addHelpBeacon( 'webtop', dh.$("menu_snapBrowser").obj, "menu_snapBrowser");
		client.addHelpBeacon( 'webtop', dh.$("menu_myVideos").obj, "menu_myVideos");
		client.addHelpBeacon( 'webtop', dh.$("menu_myPhotos").obj, "menu_myPhotos");
		client.addHelpBeacon( 'webtop', dh.$("menu_myBlogs").obj, "menu_myBlogs");
		client.addHelpBeacon( 'webtop', dh.$("menu_vault").obj, "menu_vault");
		client.addHelpBeacon( 'webtop', dh.$("menu_myForSale").obj, "menu_myForSale");
		client.addHelpBeacon( 'webtop', dh.$("menu_myContacts").obj, "menu_myContacts");
		client.addHelpBeacon( 'webtop', dh.$("menu_buddylist").obj, "menu_buddylist");
		client.addHelpBeacon( 'webtop', dh.$("menu_forums").obj, "menu_forums");
		client.addHelpBeacon( 'webtop', dh.$("menu_mySettings").obj, "menu_mySettings");

		dh.addObject("myProfile",	 		none);
		dh.addObject("ecLogo",		 		none);
		dh.addObject("loggedInAs", 			none);
		dh.addObject("loggedInAsAvatar", 	none);
		dh.addObject("layers_webtop", 		none);
		dh.addObject("layers_community",	none);
		dh.addObject("layers_contests", 	none);
		dh.addObject("layers_help",			none);
		dh.addObject("layer_cirkitvision", 	none);

		dh.addObject("windowspace", 		none);
		dh.addObject("community", 			hidden);
		dh.addObject('cirkitvision', 		none);
		dh.addObject('contests', 			hidden);
		dh.addObject('contest_profile',		hidden);

		dh.addObject("resizeAnimation", 	alwaysOnTop);

		dh.addObject('loginCanvas', 		none); //login popup
		dh.addObject('leaveRemarkCanvas', 	none); //remark popup
		dh.addObject("forumsCanvas", 		none); //forums
		dh.addObject("browseWindow", 		none); //browse
		dh.addObject("photosCanvas",		none); //carousel

		dh.addObject("videosCanvas");
			//dh.addObject("videosListWrapper", 	 none);
			//dh.addObject("videosContentWrapper", none);

		dh.addObject('musicCanvas', 		none);

		// photos remarks window
		dh.addObject('photoRemarksCanvas',	none);

		dh.addObject("popupMenu", 			hidden);
		dh.nodes.popupMenu.onResize = function(){
			var me = dh.nodes.popupMenu;
			W( getObject('popupMenu_borderT'), me.w - 20);
			H( getObject('popupMenu_borderR'), me.h - 20);
			W( getObject('popupMenu_borderB'), me.w - 20);
			H( getObject('popupMenu_borderL'), me.h - 20);
		};

		//-------------------------------
		//Event Handlers
		//-------------------------------
		var avatarDetails = getObject('avatarDetails');
		/*avatarDetails.onmouseover = function(){
			clearTimeout( client.avatarDetailsTimeoutRef );
		};*/
		avatarDetails.onmouseout = client.avatarDetailsTimeout();

		createJSButtonHover( dh.nodes.layers_webtop.obj ,	'topMenuHover' );
		createJSButtonHover( dh.nodes.layers_community.obj ,'topMenuHover' );
		createJSButtonHover( dh.nodes.layers_contests.obj ,	'topMenuHover' );
		createJSButtonHover( dh.nodes.layers_help.obj ,		'topMenuHover' );
		createJSButtonHover( dh.nodes.myProfile.obj ,		'topMenuHover' );

	//	dh.nodes.cirkitvision.onHide = 	function (){ client.turnOffMiniMenuItem(dh.nodes.cirkitvision ); 		return true; };
	//	dh.nodes.cirkitvision.onShow = 	function (){ client.turnOnMiniMenuItem( dh.nodes.cirkitvision ); 		return true; };

		dh.nodes.ecLogo.onClick = 		function(){ client.splash(); return false; };
		dh.nodes.myProfile.onClick = 	function(){ client.myProfile();	return false; };

		dh.nodes.layer_cirkitvision.onClick = 	function(){ client.openVideo( 'lifestyle' ); };
		dh.nodes.layers_webtop.onClick = 		function(){ client.openLayer('webtop'); 		return false; };
		dh.nodes.layers_community.onClick = 	function(){ client.openLayer('community'); 		return false; };
		dh.nodes.layers_contests.onClick = 		function(){ client.openLayer('contests'); 		return false; };
		//dh.nodes.layers_help.onClick = 		function(){ client.__help(); return false; };

		canvasStorage = getObject( 'canvasStorage' );

		//----------------------
		//top menu items
		//----------------------

		//mail
		dh.nodes.menu_myMail.onClick = function(){
			if ( !client.initWindow('myMail') ) return;
			client.windows.myMail.__windowToggle();
		}

		//browse window
		dh.nodes.menu_browse.onClick = function(){
			//just start the window download / init process if it's not here
			//it'll show at the end, since we requested it anyway
			//unless it's secure. then i'll ask for a login before creating
			//the window. so note the client.windows.blah reference will stll not exist.
			if ( !client.initWindow('browse') ) return;

			client.windows.browse.__windowToggle();
		}
		// social penetrator
		dh.nodes.menu_extractor.onClick = function() {
			if ( !client.initWindow('extractor') ) return;

			client.windows.extractor.__windowToggle();

		}
		//rss
		dh.nodes.menu_myRss.onClick = function() {
			if ( !client.initWindow('myRss') ) return;

			client.windows.myRss.__windowToggle();

		}
		//browser
		dh.nodes.menu_snapBrowser.onClick = function(){
			if ( !client.initWindow('snapBrowser') ) return;

			client.windows.snapBrowser.__windowToggle();
		}
		//videos
		dh.nodes.menu_myVideos.onClick = function(){
			if ( !client.initWindow('myVideos') ) return;

			client.windows.myVideos.__windowToggle();
		}
		//photos
		dh.nodes.menu_myPhotos.onClick = function(){
			if ( !client.initWindow('myPhotos') ) return;

			client.windows.myPhotos.__windowToggle();
		}
		//blogs
		dh.nodes.menu_myBlogs.onClick = function(){
			if ( !client.initWindow('myBlogs') ) return;

			client.windows.myBlogs.__windowToggle();
		}
		//vault
		dh.nodes.menu_vault.onClick = function(){
			if ( !client.initWindow('vault') ) return;

			client.windows.vault.__windowToggle();
		}
		//forsale
		dh.nodes.menu_myForSale.onClick = function() {
			if ( !client.initWindow('myForSale') ) return;

			client.windows.myForSale.__windowToggle();
		}
		//mycontacts
		dh.nodes.menu_myContacts.onClick = function() {
			if ( !client.initWindow('myContacts') ) return;

			client.windows.myContacts.__windowToggle();
		}

		//im
		dh.nodes.menu_buddylist.onClick = function(){
			if ( !client.initWindow('buddylist') ) return;

			client.windows.buddylist.__windowToggle();
		}


		//forums
		dh.nodes.menu_forums.onClick = function(){
			if ( !client.initWindow('forums') ) return;

			client.windows.forums.__windowToggle();
		}
		//settings
		dh.nodes.menu_mySettings.onClick = function(){
			if ( !client.initWindow('mySettings') ) return;
			client.windows.mySettings.__windowToggle();
		}


		//------------------------
		//Browser hooks
		//------------------------
		//dh.addResizeEvent('layout', function(){
		//
		//	delete dh.nodes.windowspace.obj.style.width;
		//	delete dh.nodes.windowspace.obj.style.height;
		//
		//	dh.nodes.windowspace.initialize();
		//
		//	dh.nodes.windowspace.moveTo( 0, dh.nodes.header.H() );
		//	dh.nodes.windowspace.resizeTo( dh.viewportW, dh.documentH - dh.nodes.header.H() );
		//
		//
		//});

		//------------------------
		//prepare pre-loaded data
		//------------------------
		client.loggedInID = loggedInID;

		//--------------------------------
		//Build Windows
		//--------------------------------
		initLogin();

		if(initLoadData.loggedUserInfo){
			client.data.userInfo = initLoadData.loggedUserInfo;
			delete initLoadData.loggedUserInfo;
		}

		if( OPENING_LAYER == 'community' ){
			client.viewUserID = viewUserID;

			client.data.viewUserInfo = initLoadData.viewUserInfo;
			delete initLoadData.viewUserInfo;

			//are we dealing with a contest profile?
			if( client.data.viewUserInfo.user_configuration.contestName ){
				OPENING_LAYER = 'contest_profile';

			} else {
				client.data.profileContacts = initLoadData.profileFriends;
				delete initLoadData.profileFriends;

				//client.data.profileRssFeeds = (!initLoadData.profileFeeds)? []:initLoadData.profileFeeds;
				//delete initLoadData.profileFeeds;

				client.data.profilePictures = initLoadData.profilePictures;
				delete initLoadData.profilePictures;

				//this does some final setup and loads setViewUser
				//client.initCommunity();
				//this will be called by openLayer if necessary.
			}

		}

		//--------------------------------
		// Client event handlers
		//--------------------------------
		client.onSwitchUser = onSwitchView;

		//--------------------------------
		// Last Steps
		//--------------------------------
		client.openLayer(OPENING_LAYER);

		//update the login / logout button
		client.login_logout();
		
		sysClock = getObject("sysClock");
		sysClockDock = getObject("sysClockDock");
		sysClock_t = setTimeout(updateSysClock,0);
	}
	//---------------
	//end init
	//---------------
	var photosTree = null;var quickTree = null;

	function updateIcon( windowID ){
		var workingWindow = client.windows[ windowID ];

		var suffix = ( workingWindow.visible ) ? ' menuActive' : '';
		dh.nodes['menu_' + windowID].obj.className = 'a menuButton' + suffix;
	}

/* *************************************
 * Profile Actions and loaders
 ***************************************/
	//---------------------------
	//Avatar Pane
	//---------------------------
	function initProfileAvatar(){

		//the first time around we'll just create the window and then wait for the onShow event to display that data
		if( !client.windows.avatar ){

			//avatar
			dh.addObject("avatarCanvas", 			none);
				dh.addObject("avatarPositioning", 	none);
				dh.addObject("avatarFloat", 		none);
				dh.addObject("avatarImage", 		none);
				dh.addObject("onlineNow", 			hidden);
				dh.addObject("avatarLastLogin", 	none);
				dh.addObject("avatarMemeberSince", 	none);
				dh.addObject("avatarURL",			none);
				dh.addObject("avatarMenu_label",	none);
				dh.addObject("avatarAgeSex",		none);
				dh.addObject("avatarLocation", 		none);

			client.addWindow( 'avatar',
				{
					startingState:		windowState.normal,
					windowSizing:		windowSizing.fillHoriz,
					windowPositioning: 	windowPositioning.floatLeft,
					windowStyle:		windowStyle.canvas,
					resizable :			false
				},
				dh.nodes.profile_column1.obj,
				"Avatar"
			);
			client.windows.avatar.setCanvas( dh.nodes.avatarCanvas );
			client.windows.avatar.onShow = initProfileAvatar;

			client.addHelpBeacon("community",getObject("avatarMenu_add"),"avatarMenu_add");
			client.addHelpBeacon("community",getObject("avatarMenu_remark"),"profileLeaveRemarkButton");
			client.addHelpBeacon("community",getObject("avatarMenu_mail"),"avatarMenu_mail");
			return;
		}

		//are we browsing ourself or another?
		if( client.viewUserID == client.loggedInID ||
			client.viewUserID == -1){
			displayProfileAvatar( client.data.userInfo );
			dh.nodes.onlineNow.show();
		}else {
			displayProfileAvatar( client.data.viewUserInfo );
			if( parseInt( client.data.viewUserInfo.profile_info.online ) > 0 ){
				dh.nodes.onlineNow.show();
			} else {
				dh.nodes.onlineNow.hide();
			}
		}
	}

	function initProfileContacts(){

		if( !client.windows.profile_contacts ){

			dh.addObject("profileContactsCanvas", none); //profile contacts
			dh.addObject("profileContactsList", none);
			dh.addObject("profileContactsPaginator", none);

			//---------------------------
			// Contacts
			//---------------------------
			client.addWindow( 'profile_contacts',
				{
					startingPosition: 	[/*x*/ 0, /*y*/ 0],
					windowStyle:		windowStyle.pane,
					windowPositioning:	windowPositioning.floatLeft,
					windowSizing:		windowSizing.fillHoriz,
					startingState:		windowState.normal,
					fadeInOut:			false,
					resizable:			false,
					closeButton:		false,
					shadeButton:		true,
					maximizeButton: 	false,
					minimizeButton: 	false,
					showTabs:			false,
					showStatus:			true,
					showTitle:			true,
					showIcon:			false,
					draggable: 			false
				},
				dh.nodes.profile_column2.obj,
				"Contacts"
			);
			client.windows.profile_contacts.setCanvas(dh.nodes.profileContactsCanvas);
			client.windows.profile_contacts.onShow = displayProfileContacts;

			client.addHelpBeacon("community",getObject("profileContactsQuick"),"profileContactsQuick");
		}
	}

	var abbrMonthAry = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
	function formatDateString( str ){
		try{
		var year = str.replace(/(\d\d\d\d)-(\d\d)-(\d\d)\s(\d\d):(\d\d):(\d\d)/,'$1');
		var month = str.replace(/(\d\d\d\d)-(\d\d)-(\d\d)\s(\d\d):(\d\d):(\d\d)/,'$2');
		var day = str.replace(/(\d\d\d\d)-(\d\d)-(\d\d)\s(\d\d):(\d\d):(\d\d)/,'$3');
		var day1 = day.replace(/(\d)(\d)/,'$1');
		var day2 = day.replace(/(\d)(\d)/,'$2');

		if(day1 == '1')day = day1+day2+"th";
		else{
			var post = "th";
			switch(day2){
				case "1":
					post = "st";
					break;
				case "2":
					post = "nd";
					break;
				case "2":
					post = "rd";
					break;
			}
			if(parseInt(day1))day = day1+day2+post;
			else day = day2+post;
		}

		return abbrMonthAry[(parseInt(month)- 1 )]+". "+day+" "+year;
		}catch(ex){
			return str;
		}
	}

	function displayProfileAvatar( info ){
		var date = new Date();
		date = date.getMilliseconds();

		if(info.last_login.match(/\d\d\d\d-\d\d-\d\d\s\d\d:\d\d:\d\d/)){
			info.last_login = formatDateString( info.last_login );
			info.profile_info.create_date = formatDateString( info.profile_info.create_date  );
		}

		dh.nodes.avatarLastLogin.write( info.last_login );
		dh.nodes.avatarMemeberSince.write( info.profile_info.create_date );

		if(info.user_details.age){
			dh.nodes.avatarAgeSex.write(info.user_details.age + "/" + info.user_details.sex);
		}else{
			dh.nodes.avatarAgeSex.write('');
		}
		if(info.user_details.location){
			dh.nodes.avatarLocation.write(info.user_details.location);
		}else{
			dh.nodes.avatarLocation.write("");
		}


		dh.nodes.avatarURL.setValue( 'www.ecirkit.com/' + info.profile_info.url_name );
		dh.nodes.avatarImage.setImage( '/api/servlets/images?blop='+date+'&type=avatar&size=188&user_id=' + info.profile_info.user_id, avatarImageLoaded );
	}

	function avatarImageLoaded(){
		dh.nodes.avatarImage.initialize();
		dh.nodes.avatarFloat.resizeTo(dh.nodes.avatarImage.w , dh.nodes.avatarImage.h);
		dh.nodes.avatarPositioning.X( (dh.nodes.avatarCanvas.getW() - dh.nodes.avatarFloat.w) / 2 );
		dh.nodes.avatarPositioning.Y( (dh.nodes.avatarPositioning.h - dh.nodes.avatarImage.h) / 2 );
	}

	function onSwitchView(){
		if( client.windows.browse.visible ){ client.windows.browse.minimize(); }
		if( client.windows.forums.visible ){ client.windows.forums.minimize(); }
		return true;
	}

 	//-------------------------
 	//Profile Contacts Browser
 	//-------------------------

 	//displays the first 6 contacts
	function displayProfileContacts(){

		dh.nodes.profileContactsPaginator.purge();
		client.windows.profile_contacts.setTitle("Contacts");
		client.windows.profile_contacts.windowNode.resizeTo(dhNull,180);
		client.windows.profileMusic.windowNode.resizeTo(dhNull,345);
		client.windows.profile_contacts.currentCanvas.obj.style.overflow = "hidden";

		if( !client.data.profileContacts ){
			ajax.post( '/api/processors/friends',
				{
					type: 'profileFriends',
					i : client.getBrowseUserID()
				},
				function (connectionInstance) {
					if(connectionInstance.responseObject){
						if(connectionInstance && connectionInstance.responseObject && connectionInstance.responseObject.error){
							switch( connectionInstance.responseObject.error ){
								case '6675':
										getObject('profileContactsList').innerHTML = '<img src="/images/perms/small_friends.png" />';
										var ac = getObject('allContacts');
										if (ac){
											ac.innerHTML = '';
										}
										return false;
									break;
							}
						}else{
							client.data.profileContacts = connectionInstance.responseObject;
							displayProfileContacts();
						}
					}
				} ,
				function (connectionInstance) {

				},
				client.windows.profile_contacts
			);
		} else {

			dh.nodes.profileContactsList.purge();

			for( var tmpIndex = 0; tmpIndex < client.data.profileContacts.length ; tmpIndex++){
				var tmpAvatar = client.data.profileContacts[tmpIndex];
				displayUserAvatar( dh.nodes.profileContactsList.obj , tmpAvatar, true, true, true );
			}
			var allFriends = getObject("allContacts");
			if( allFriends ){
				allFriends.parentNode.removeChild(allFriends);
			}
			var allFriends = createObject("div", "allContacts", "managementLink managementLink_statusBar", client.windows.profile_contacts.statusBar.obj, "View All Contacts");
			allFriends.onclick = function(){delete client.data.profileContacts; fetchAllProfileContacts(0)};
			if(dh.nodes.profileContactsList.obj.offsetHeight > dh.nodes.profileContactsList.obj.scrollHeight){
				W(dh.nodes.profileContactsList.obj,getW(dh.nodes.profileContactsList.obj) - 10);
				X(dh.nodes.profileContactsList.obj,10);
			}else{
				dh.nodes.profileContactsList.obj.style.width = "100%";
				X(dh.nodes.profileContactsList.obj,0);
			}
		}
	}

	var contactsPerPage = 54;
	var fetchingContacts = true;
	function fetchAllProfileContacts( startIndex ){
		fetchingContacts = true;
		if(!parseInt(startIndex)){var startIndex = 0;}
		ajax.post( '/api/processors/friends',
		{
			type: 'friendsPage',
			i : client.getBrowseUserID(),
			s:startIndex,
			e:contactsPerPage
		},
		function (connectionInstance) {
			if(connectionInstance && connectionInstance.responseObject && connectionInstance.responseObject.error){
				switch( connectionInstance.responseObject.error ){
					case '6675':
							getObject('profileContactsList').innerHTML = '<table height="100%" width="100%"><tbody><tr><td height="100%" width="100%" align="center"><img src="/images/perms/windshield.png" /></td></tr></tbody></table>';
							client.windows.profile_contacts.windowNode.resizeTo(dhNull,425);
							client.windows.profileMusic.windowNode.resizeTo(dhNull,589);
							return false;
						break;
				}
			}else if(connectionInstance.responseObject){
				dh.nodes.profileContactsPaginator.purge();
				dh.nodes.profileContactsList.purge();
				client.windows.profile_contacts.setLoading(true);
				client.windows.profile_contacts.setStatus("Building Avatars");
				delete client.data.profileContacts;
				client.data.profileContacts = connectionInstance.responseObject;
				client.data.profileContacts["startIndex"] = startIndex;
				client.windows.profile_contacts.windowNode.resizeTo(dhNull,425);
				client.windows.profileMusic.windowNode.resizeTo(dhNull,589);


				if(!client.data.profileContacts["totalFriends"]){
					client.data.profileContacts["totalFriends"] = 0;
					client.data.profileContacts.contacts = [];
				}
				//client.windows.profileMusic.windowNode.resizeTo(dhNull,590);
				setTimeout(function(){displayAllProfileContacts(startIndex)},0);
				client.windows.profile_contacts.setTitle("Contacts - "+client.data.profileContacts["totalFriends"]);
				var allFriends = getObject("allContacts");
				if(allFriends ){
					allFriends.parentNode.removeChild(allFriends);
				}
				var allFriends = createObject("div", "allContacts", "managementLink managementLink_statusBar", client.windows.profile_contacts.statusBar.obj, "View Top 6");
				allFriends.onclick = function(){delete client.data.profileContacts; displayProfileContacts(0)};
			}
		} ,
		function (connectionInstance) {},
		client.windows.profile_contacts
		);
	}

	function displayAllProfileContacts(start){
		dh.nodes.profileContactsPaginator.purge();
		dh.nodes.profileContactsList.purge();
		dh.nodes.profileContactsList.obj.style.overflow = "auto";

		var numPages = Math.ceil((client.data.profileContacts["totalFriends"])/contactsPerPage);
		var currPage = (Math.floor((start - 1)/contactsPerPage)) + 1;
		var pageMenu = createObject("div",'','profileVCRMenu',dh.nodes.profileContactsPaginator.obj,'');
		var pagination = '';
		if(numPages > 20){
			pagination = remarkpaginator2000(currPage , numPages,"fetchAllProfileContacts",contactsPerPage);
		}else{
			for(var i = 0 ; i < numPages ; i++){
				if(currPage ==  i) {
					pagination += " <strong class=\"browsePage selected_yellow\">" + (i + 1) + "</strong>";
				} else {
					pagination += " <span class=\"browsePage\" onclick=\"fetchAllProfileContacts('"+((i)*contactsPerPage)+"');\">" + (i + 1) + "</span> ";
				}
			}
		}
		var buttonsDiv = createObject('div','','remarksVCRButtons',pageMenu,pagination);

		for( var tmpIndex = 0; tmpIndex < client.data.profileContacts["contacts"].length ; tmpIndex++){
			var tmpAvatar = client.data.profileContacts["contacts"][tmpIndex];
			displayUserAvatar( dh.nodes.profileContactsList.obj , tmpAvatar, true, true, true );
		}
		fillVertically(dh.nodes.profileContactsList.obj);
		if(dh.nodes.profileContactsList.obj.offsetHeight >= dh.nodes.profileContactsList.obj.scrollHeight){
			W(dh.nodes.profileContactsList.obj,getW(dh.nodes.profileContactsList.obj) - 11);
			X(dh.nodes.profileContactsList.obj,10);
		}else{
			dh.nodes.profileContactsList.obj.style.width = "100%";
			X(dh.nodes.profileContactsList.obj,0);
		}
		fetchingContacts = false;
		client.windows.profile_contacts.setStatus("Idle");
		client.windows.profile_contacts.setLoading(false);
	}

/****************************
	Avatar menu functions
****************************/

function sendProfileEmail(){

	// are we viewing our own profile?
	if (client.getUserID() == client.getBrowseUserID()){
		client.userError("E-mail", "You're viewing your own profile. You cannot perform this action.");
		return false;
	}

	if (!client.windows.myMail){
		client.initWindow('myMail', function(){ email.composeProfileEmail(); });
	}else{
		email.composeProfileEmail();
		if( !client.windows.myMail.visible ){
			client.windows.myMail.show();
		}
	}
	return true;
}

function contactRequest(loginResponse){

	// are we viewing our own profile?
	if (client.getUserID() == client.getBrowseUserID()){
		client.userError("Contact Request", "You're viewing your own profile. You cannot perform this action.");
		return false;
	}

	switch (loginResponse){
		case "cancel":
		case "failure":
			client.userError("Cannot open window", "The window you are typing to open requires a login. Please log in to open this window.");
			break;
		case "success":
			doContactRequest();
			break;
		default:
			if(!client.isLoggedIn()){
				client.login_logout(true, contactRequest);
			}else{
				doContactRequest();
			}
			break;
	}
}

function doContactRequest(){
	ajax.post('/api/processors/messaging',
		{
			type: 'sendContactRequest',
			i: client.getBrowseUserID()
		},
		function (connectionInstance){
			if (connectionInstance.serverResponse == 'false'){
				client.userError('Contact Request', 'Contact request failed. Please try again');
			}else if (connectionInstance.responseObject.Error){
				client.userError('Contact Request', connectionInstance.responseObject.Error);
			}else if (connectionInstance.serverResponse == 'ok'){
				client.userNotice('Contact Request', 'Your contact request has been sent.');
			}
		},
		function (connectionInstance){

		},
		client.windows.avatar
	);
}

function initQuickSearch(){
	var name = "quickSearch";
	if(!client.windows[name]){
		client.addWindow( name,
				{
					startingPosition: 	[ 0, 0],
					windowStyle:		windowStyle.pane,
					windowPositioning:	windowPositioning.absolute,
					windowSizing:		windowSizing.manual,
					startingState:		windowState.minimized,
					centerOnShow:		false,
					fadeInOut:			false,
					resizable:			true,
					closeButton:		true,
					reloadButton:		true,
					shadeButton:		false,
					maximizeButton: 	true,
					minimizeButton: 	false,
					showTabs:			false,
					showStatus:			false,
					showTitle:			true,
					showIcon:			false,
					draggable: 			true
				},
				dh.nodes.windowspace.obj,
				"Quick Search"
			);
		win = client.windows[name];
		win.setCanvas(dh.createDHObject("div","quickSearchCanvas","contentCanvas a o f",canvasStorage));
		win.searchData = {};

		win.onReload = function(){printResults();};

		win.normalSize=[850,400];
		win.onShow = function(){printResults();};

	}
}
function printResults(){
	dh.nodes.quickSearchResults.purge();
	for(index in client.windows.browse.quickSearchData){
		var data = client.windows.browse.quickSearchData[index];
		displayUserAvatar(dh.nodes.quickSearchResults.obj ,data,true,true,false,false);
	}
	getObject('quickSearchResultsPagination').innerHTML = (Math.ceil(client.windows.browse.totalQuickCount/perQSearch) <= 20)?
		noPaginationHTML( client.windows.browse.currentQuickPage, Math.ceil(client.windows.browse.totalQuickCount/perQSearch) ,"client.windowFunctions.browse.paginate")
		:remarkpaginator2000( client.windows.browse.currentQuickPage , Math.ceil(client.windows.browse.totalQuickCount/perQSearch) ,"client.windowFunctions.browse.paginate",perQSearch );
}
function setAndLoadQuickSearch(data,dispName,start){
	client.windows.browse.quickSearchData = data.results;
	client.windows.browse.totalQuickCount = data.totalCount;
	client.windows.browse.currentQuickSearch = dispName;
	client.windows.browse.currentQuickPage = (start)?Math.floor( ( parseInt(start) - 1) / perQSearch )  + 1 : 0;
	dh.nodes.quickSearchCanvas.obj.childNodes[0].childNodes[0].childNodes[0].value = dispName;
	//if(!client.windows.browse.currentQuickPage)client.windows.browse.currentQuickPage++;
	client.windows.browse.show();
	client.windows.browse.__tab(1);
}
var perQSearch = 25;
function quickSearch(e, dispName, start ){
	if(!e)var e = window.event;

		if((e.keyCode || e.which) == 13) {
			ajax.post(
				'/api/processors/quickSearch',
				{type:"quickSearch",q:dispName,s:start,e:perQSearch},
				function(conn){
					if(conn.responseObject && conn.responseObject.totalCount){
						client.initWindow('browse',function(){setAndLoadQuickSearch(conn.responseObject,dispName,start)})
						//console.log(conn.responseObject);
					}else{
						client.userNotice("User Search","Sorry, no people with a name like that.");
					}
				},
				'',
				client.windows.browse
			);
	}
}
function leaveARemark(){
	leaveRemark('saveRemark',null,'userRemarks',client.windows.windshield);
}
// key codes
// http://www.cambiaresearch.com/c4/702b8cd1-e5b0-42e6-83ac-25f0306e3e25/Javascript-Char-Codes-Key-Codes.aspx
function hotKeysDown( e ){
	if(!e)var e = window.event;
	if((e.keyCode || e.which) == 16) {
		shift = true;
		return false;
	}
	if((e.keyCode || e.which) == 17) {
		cntrl = true;
		return false;
	}
	if((e.keyCode || e.which) == 18) {
		alt = true;
		return false;
	}
	// alt + left arrow
	if((e.keyCode || e.which) == 37) {
		if(alt){
			if(client.isLoggedIn()){
				alert("Look "+client.data.userInfo.profile_info.first_name+", I can see you're really upset about this. I honestly think you ought to sit down calmly, take a stress pill, and think things over. ");
			}
			alt = false;
			return false;
		}
		return true;
	}
	// ctrl + h
	if((e.keyCode || e.which) == 72) {
		if(cntrl && shift){
			client.__help();
			cntrl = false;
			shift = false;
			return false;
		}
		return true;
	}
	// ctrl + '
	if((e.keyCode || e.which) == 222) {
		if(cntrl && shift){
			alert('Congradulations Carbon, by finding this you have become the geekiests tester ever.');
			cntrl = false;
			shift = false;
			return false;
		}
		return true;
	}
	// ctrl + p
	if((e.keyCode || e.which) == 80) {
		if(cntrl && shift){
			client.initWindow("myPhotos",function(){if(!client.windows.myPhotos.visible)client.windows.myPhotos.show();});
			cntrl = false;
			shift = false;
			return false;
		}
		return true;
	}

	return true;
}

function hotKeysUp( e ){
	if(!e)var e = window.event;
	if((e.keyCode || e.which) == 16) {
		shift = false;
		return false;
	}
	if((e.keyCode || e.which) == 17) {
		cntrl = false;
		return false;
	}
	if((e.keyCode || e.which) == 18) {
		alt = false;
		return false;
	}
	return true;
}
function fetchProfileForSale(){
	if( client.data.profileForSale ) return true;

	dh.nodes.forSaleCanvas.purge();
	ajax.post( '/api/processors/user',
		{
			type: 'forSale',
			i : client.getBrowseUserID()
		},
		function (connectionInstance) {
			if(connectionInstance && connectionInstance.responseObject && connectionInstance.responseObject.error){
					switch( connectionInstance.responseObject.error ){
						case '6675':
								getObject('forSaleCanvas').innerHTML = '<table height="100%" width="100%"><tbody><tr><td height="100%" width="100%" align="center"><img src="/images/perms/windshield.png" width="100%" /></td></tr></tbody></table>';
								return false;
							break;
					}
			}else if(connectionInstance.responseObject){
				client.data.profileForSale = connectionInstance.responseObject;
				if(!client.data.profileForSale.ec){
					client.data.profileForSale.ec = [];
				}
				displayProfileForSale();
			}
		} ,
		function (connectionInstance) {

		},
		client.windows.windshield
	);
}

function displayProfileForSale(){

	for (var i = 0; i < client.data.profileForSale.ec.length; i ++){
		var item = client.data.profileForSale.ec[i];

		var itemWrapper = createObject('div', 'myForSaleItemWrapper_' + i, 'myForSaleItemWrapper', dh.nodes.forSaleCanvas.obj);
			var itemTitle = createObject('div', 'myForSaleItemTitle_' + i, 'myForSaleItemTitle gtl', itemWrapper, item.name);

			if (item.images.length > 0){
				var itemAllImagesWrapper = createObject('div', 'myForSaleAllImagesWrapper_' + i, 'myForSaleAllImagesWrapper', itemWrapper);
				for (var j = 0; j < item.images.length; j ++){
					var imgSrc = '/api/servlets/ecImages?file=' + item.images[j].image + '&type=forsale&user_id=' + client.getBrowseUserID()  + '&height=150&width=150';
					var itemImageWrapper = createObject('div', 'myForSaleImageWrapper_' + i + '_' + j, 'myForSaleImageWrapper', itemAllImagesWrapper);
					itemImageWrapper.innerHTML += '<img src="' + imgSrc + '" id="myForSaleItemImage_' + i + '" onclick="showImage(\'/api/servlets/ecImages?file=' + item.images[j].image + '&type=forsale&user_id=' + client.getBrowseUserID()  + '&height=800&width=800\');">';
				}
			}

			var itemInfoWrapper = createObject('div', 'myForSaleItemInfoWraper_' + i, 'myForSaleItemInfoWrapper r', itemWrapper);

				var itemDescription = createObject('div', 'myForSaleItemDesc_' + i, 'myForSaleItemDesc gtm r', itemInfoWrapper, item.description);
				var itemPriceWrapper =  createObject('div', dhNull, 'myForSaleItemPriceWrapper r fh', itemInfoWrapper);
				var itemPrice = createObject('div', 'myForSaleItemPrice_' + i, 'myForSaleItemPrice gtm', itemPriceWrapper, "<strong>Price: </strong>" + item.price);

	}

	if (client.data.profileForSale.ebay && client.data.profileForSale.ebay.items && client.data.profileForSale.ebay.items.length > 0){

		for (var i = 0; i < client.data.profileForSale.ebay.items.length; i ++){
			var item = client.data.profileForSale.ebay.items[i];
			var itemWrapper = createObject('div', 'myForSaleItemWrapper_' + i, 'myForSaleItemWrapper', dh.nodes.forSaleCanvas.obj);
			var itemTitle = createObject('div', 'myForSaleItemTitle_' + i, 'myForSaleItemTitle gtl', itemWrapper, item.favicon + '&nbsp;' + item.title);
			var itemInfoWrapper = createObject('div', 'myForSaleItemInfoWraper_' + i, 'myForSaleItemInfoWrapper', itemWrapper);
			var itemDescription = createObject('div', 'myForSaleItemDesc_' + i, 'myForSaleItemDesc gtm', itemInfoWrapper, item.description);
		}
	}
	//dh.nodes.dhWin_windshield.resizeTo(dhNull, 1000);
	//client.windows.windshield.__resize();
}


/*****************************
	settings
		header:,
		menu:,
		breadcrumb:
		display:  /icons, details, list, gallery/
		window:
		initData:
*****************************/

/****************************
 *
 * @param {Object} pane - pane to be placed in. IT MUST HAVE A WIDTH!!!!
 * @param {Object} root - user -1 for now
 * @param {Object} settings - see above
 * @param {Object} name - type of file tree, Generic is all that is done.
 *
 ****************************/
function FileTree( pane , root, settings, name){
	this.pane = pane;
	this.root = root;
	this.wrkDir = root;
	this.wrkFile = root;
	this.settings = settings;
	this.name = name;
	this.processor = "/api/processors/"+this.name+"Processor";
	this.schema = FileSchema[name];
	this.functions = FileFunctions[name];
	this.context = FileContext[name];
	this.menu = FileMenu[name];
	this.setId( pane , root );
	this.stackA = new ObjStack();
	this.stackB = new ObjStack();
//	this.ajax = new Ajax();
	this.ajax = ajax;
	this.indexSchema();
}

FileTree.prototype = {

	id:null,
	index:null,
	files:null,
	wrkDir:null,
	wrkFile:null,
	loaded:false,
	stackA: null,
	stackB: null,
	stack: "A",

	pane:null,
	list:null,
	sideBar:null,
	root:null,
	wrkDir: null,
	settings:null,
	name:'',
	processor:'',
	schema:null,
	functions:null,
	context:null,
	ajax:null,

	setId : function( pane , root ){
		if(pane.id == ''){
			this.id = "tree_"+root;
			pane.id = this.id;
		}else{
			this.id = pane.id;
		}
		this.pane.tree = this;

		this.pane.style.width = "100%";
		this.pane.style.overflow = "hidden";
		var treeDH = null;
		if(!(treeDH = dh.$(this.id))){
			treeDH = dh.addObject(this.id);
		}
		if(!treeDH.onResize)
			treeDH.onResize = this.__resize;
	},

	indexSchema : function(){
		this.index = new Array();

		for(var id in this.schema){
			this.index[this.index.length] = id;
		}
	},

	indexFiles : function( dataAry ){
		delete this.files;
		this.files = new Array();
		
		var limit = dataAry.length;
		for(var x = 0; x < dataAry.length; x++){
			this.files[dataAry[x].id] = dataAry[x];
		}
		this.dataAry = dataAry;
	},
	
	countFiles : function(){
		if(this.dataAry)
			return this.dataAry.length;
		else	return 0;
	},
	
	loadFiles : function( fileId,callback ){
		var getData = null;
		var thisTree = this;
		this.pane.innerHTML = '';
		var html = '';
		delete thisTree.files;

		var buildTree = function(data,nestCallback){
 			thisTree.indexFiles(data);
 			setTimeout(function(){
 				thisTree.fullRefresh()
 				if(nestCallback){thisTree.callback = nestCallback;}
		 		if(thisTree.callback){thisTree.callback();}
 			},0);
			return true;
		}
		if(!this.settings.initData){
			getData = {action:"getFolders",i:client.getBrowseUserID(),window:this.name,parent:this.root};
		 	this.ajax.post(this.processor,getData,
		 		function( conn ){
		 			if(conn && conn.responseObject && conn.responseObject.error){
						switch( conn.responseObject.error ){
							case '6675':
									thisTree.pane.innerHTML = '<table height="100%" width="100%"><tbody><tr><td height="100%" width="100%" align="center"><img src="/images/perms/carousel.png" /></td></tr></tbody></table>';
									return false;
								break;
						}
					}
		 			else if(conn && conn.responseObject){buildTree(conn.responseObject,callback);}
		 		},null,thisTree.settings.window);
		}else{
			buildTree(this.settings.initData);
			delete this.settings.initData;
		}
	},

	fullRefresh : function(  ){
		dh.$(this.pane.id).purge();
		var thisTree = this;

		if(this.settings.msg){
			this.displayMsg();
		}

		if(this.settings.menu){
			this.displayMenu();
		}

		if(this.settings.breadcrumb){
			this.displayBreadCrumb();
		}

		if(this.settings.header){
			this.displayHeader();
		}

		this.list = document.createElement("div");
		this.list.id = this.id+"_list";
		this.list.className = "r fileList";
		this.list.type = "list";
		this.list.oncontextmenu = function(e){if(this.context){thisTree.displayContext( thisTree.list , e );return false;}};
		this.pane.appendChild( this.list );
		dh.addObject(this.list.id,none);

		if(this.settings.sideBar){
			this.displaySideBar();
		}
		this.__resize();
		this.refresh();
	},

	refresh : function(){
		this.list.innerHTML = '';
		if(this.settings.display == 'details' || this.settings.display == 'list' || this.settings.display == 'grid'){
			this.displayRows();
		}else if(this.settings.display == 'icons'){
			this.displayIcons();
		}else if(this.settings.display == 'gallery'){
			this.displayGallery();
		}else if(this.settings.display == 'photoMan'){
			this.displayPhotoMan();
		}
		if(this.settings.window){
			this.settings.window.__resize();
		}
	},

	displayMsg : function(){
		var msg = this.settings.msg;
		var msgDiv = document.createElement("div");
		msgDiv.id = this.id+"_msgBox";
		msgDiv.className = "msgRow";
		msgDiv.innerHTML = msg;
		this.pane.appendChild(msgDiv);
	},

	displayMenu : function( ){
		var menuDiv = document.createElement("div");
		var thisTree = this;
		var temp = null;
		menuDiv.id = this.id+"_menuBox";
		menuDiv.className = "row dirRow menuRow";
		menuDiv.style.overflow = "hidden";
		for(key in this.menu){
			temp = createObject("div",this.id+"_"+this.menu[key]["id"],"active fl gt", menuDiv,"&nbsp;&nbsp"+this.menu[key]["value"]);
			temp.onclick = Function("var tree = getObject('"+thisTree.id+"').tree;tree."+thisTree.menu[key]["func"]+"(tree.id+'_list');");
			/*client.addHelpBeacon("community",temp,temp.id);
			client.addHelpBeacon("webtop",temp,temp.id);*/
		}
		this.pane.appendChild(menuDiv);
	},

	displayBreadCrumb : function(){
		var bread = createObject("div",this.id+"_Bread","row dirRow breadRow",dhNull,this.buildBreadCrumb(this.root));
		this.pane.appendChild(bread);
		
		this.bread = bread;
		/*client.addHelpBeacon("community",this.bread.lastChild,'slideToggle');*/
	},

	buildBreadCrumb : function( folderId ){
		var thisTree = this;
		var ancObj = thisTree.ancestoryObj(folderId);
		var split = ancObj.string.split('->');

		var html = '<div class="p fl" onclick="getObject(\''+thisTree.id+'\').tree.openFolder('+folderId+')">'+ancObj.string+'</div>';
		for(key in split){
			html = html.replace(eval('/('+split[key]+')->/'),"<div class='active fl' style='color:orange;' onclick='getObject(\""+thisTree.id+"\").tree.openFolder("+ancObj.ary[key]+")'>$1-></div>");
		}

		//if(folderId != this.root){
			html += '<div '+
					'id="'+this.id+'_slideBtn"'+
					'onclick="getObject(\''+this.id+'\').tree.displaySlideShow('+folderId+')"'+
					'style="position:absolute;right:0px;height:100%;top:0px;" '+
					'>'+
						'<div class="iconText">'+
							'<div class="tanIconText" style="line-height:24px;color : white;margin-right:3px;float : left;">Start Slide Show</div>'+
							'<div class="icon24 playBtn"></div>'+
						'</div>'+
					'</div>';
		//}
		return html;
	},

	displaySideBar : function (){
		var tempBar = document.createElement("div");
		tempBar.id = this.id+"_sideBar";
		tempBar.className = "r fileSidebar hide";
		this.list.className += " withSide";
		this.pane.insertBefore(tempBar,this.list);
		this.sideBar = tempBar;
		this.buildSideBar();
		this.sideBar.className = this.sideBar.className.replace(/\shide/,'');
		this.sideBar.canvas.tree.__resize();
	},

	buildSideBar : function (){
		var thisTree = this;
		var title = createObject("div",dhNull,"r fh sideTitle",this.sideBar,'<div id="'+this.id+'_closeSide" class="close active"><img src="/' + ecirkitImagesURL + 'forums/blowout.png"></div>');
		var closeButton = getObject(this.id+'_closeSide');

		closeButton.expanded = true;
		closeButton.onclick = function(){thisTree.toggleSidebar(closeButton)};
		var canvas = createObject("div",this.sideBar.id+"_canvas","r fh sideCanvas",this.sideBar,'');
		this.sideBar.canvas = canvas;
		this.sideBar.titleBar = title;
		dh.addObject(this.sideBar.id,none);
		dh.addObject(canvas.id,none);
		canvas.tree = new FileTree(
				canvas ,
				-1 ,
				{
					header:false,
					menu:false,
					msg:false,
					sideBar:false,
					display:"list",
					window:client.windows.carousel
				} ,
				thisTree.name
			);canvas.tree.files = this.files;canvas.tree.fullRefresh();
	},

	resizeSideBar : function( totalH , totalW){
		try{
			var bar = this.sideBar;
			var titleH = getH(bar.titleBar);
			bar.style.height = (totalH)+"px";
			bar.canvas.style.height = (totalH - titleH)+"px";
			var w = getW(bar);
			if(dh.$(bar.canvas.id)){
				dh.$(bar.canvas.id).onResize();
			}
			return (totalW - w);
		}catch(ex){
			
			return 0;
		}
	},

	hideSideBar : function (){
		var thisTree = this;
		var closeW = getW(getObject(this.id+'_closeSide'));
		var sideBar = dh.$(this.sideBar.id);
		sideBar.animate(dh.tweenDetails(dhNull,dhNull,closeW,dhNull,dhNull,.33,3),
			function(){
				var w = getW(thisTree.pane);
				thisTree.list.style.width= (w - closeW)+"px";
				return true;
			});
		/*this.sideBar.className += " sideClose";
		this.list.className += " withSideClose";*/
	},

	showSideBar : function(){
		var thisTree = this;
		var w = getW(thisTree.pane);
		var end = parseInt(w * .2);
		var sideBar = dh.$(this.sideBar.id);
		thisTree.list.style.width= (w - 150)+"px";
		sideBar.animate(dh.tweenDetails(dhNull,dhNull,150,dhNull,dhNull,.33,3),
			function(){
				return true;
			});
		/*this.sideBar.className = this.sideBar.className.replace(/\ssideClose/,'');
		this.list.className = this.list.className.replace(/\swithSideClose/,'');*/
	},

	toggleSidebar : function ( button ){
		if(button.expanded){
			button.expanded = false;
			dh.$(this.sideBar.canvas.id).hide();
			this.hideSideBar();
		}else{
			button.expanded = true;
			dh.$(this.sideBar.canvas.id).show();
			this.showSideBar();
		}
	},

	setMenu : function( obj ){
		var menuDiv = getObject(this.id+"_menuBox");
		menuDiv.innerHTML = '';
		menuDiv.appendChild(obj);
	},

	displayHeader : function(){
		var row = document.createElement("div");
		var self = this;
		var temp = null;
		row.id = this.id+"_header";
		row.className = "headerRow";

		var start = true;
		for(var key in this.schema){
			temp = document.createElement('div');
			temp.id = key+'_header';
			temp.className = "cell";
			temp.style.width = this.schema[key]+'%';
			if(start){
				temp.innerHTML = "<div class='cell wSpace' style='width:5%'></div>";
				temp.innerHTML +="<div class='cell nSpace' style='width:95%'>"+key+"</div>";
				start = false;
			}else{
				temp.innerHTML = key;
			}
			row.appendChild(temp);
		}

		this.pane.appendChild(row);
	},

	displayRows : function(){
		var stack = eval("this.stack"+this.stack);
		var thisTree = this;
		stack.length = 0;
		for(var index in this.files){
			var data = this.files[index];
			data.depth = 1;
			if(data.parent == this.root){
				this.list.appendChild(this.buildRow(data));
			}else{
				stack.push(data);
			}
		}
		this.insertFiles();
	},

	displaySlideShow : function( fileId ){
		var thisTree = this;
		this.list.onscroll = null;
		this.list.style.textAlign = "center";
		//createFlash(this.list, '/flash/slideshow.swf?f='+fileId, 'slideShow_'+fileId, getW(this.list) - 10, getH(this.list) - 10, true,'galleryURL=/api/xml/p.php?f='+fileId);
		
		var html = '<iframe style="height:300px;width:400px;position:relative;top:30px;" src="/api/servlets/imgWidget?f='+fileId+'&q='+client.getBrowseUserID()+'"></iframe>';
		this.list.style.background = "#000000";
		this.list.innerHTML = html;
		
		
		
		var button = this.bread.lastChild;
		button.onclick = function(){thisTree.openFolder(fileId)};
		button.innerHTML = 	'<div class="iconText">'+
								'<div class="tanIconText" style="float : left;line-height:24px;color : white;margin-right:3px;">Stop Slide Show</div>'+
								'<div class="icon24 xSquareBlue24"></div>'+
							'</div>';

			var html = 	'<div class="fh r">'+
						'<input class="fh" type="input" maxlength="999999"  style="background:#FFFFFF url(/images/inputbg.png);" value="'+
							'<iframe '+
								'style=&quot;height:300px;width:400px&quot; '+
								'src=&quot;http://'+ document.location.hostname + ((document.location.port)? (':'+document.location.port) : '')+'/api/servlets/imgWidget?f='+fileId+'&q='+client.getBrowseUserID()+'&quot;>'+
							'</iframe>'+
/*
							'<object width=&quot;210&quot; height=&quot;95&quot;>'+
							'<param value=&quot;http://'+ document.location.hostname + ((document.location.port)? (':'+document.location.port) : '')+'/flash/slideshow.swf?f='+fileId+'&quot; name=&quot;movie&quot;/>'+
							'<param value=&quot;galleryURL=http://'+ document.location.hostname + ((document.location.port)? (':'+document.location.port) : '')+'/api/xml/p.php?f'+fileId+'&quot; name=&quot;flashvars&quot;/>'+
							'<embed	width=&quot;420&quot; height=&quot;200&quot; '+
									'wmode=&quot;transparent&quot; '+
									'type=&quot;application/x-shockwave-flash&quot; '+
									'src=&quot;http://'+ document.location.hostname + ((document.location.port)? (':'+document.location.port) : '')+'/flash/slideshow.swf?f='+fileId+'&quot; '+
									'flashvars=&quot;galleryURL=http://'+ document.location.hostname + ((document.location.port)? (':'+document.location.port) : '')+'/api/xml/p.php?f='+fileId+'&quot;/>'+
						'</object>'+
*/

						'" '+
						'style="height:85%; width:95%"'+
						'class="text" '+
						'onclick="this.select()"'+
						'onmouseover="descriptionPop(\'HTML Code<br/>Copy and Post right on your favorite websites.\')"'+
						'onmouseout="unregisterToolTip()"'+
						'id="photoEditUrl" name="photoEditUrl" maxlength="100" class="a o" />'+			
					'</div>';
			var obj = createObject("div",dhNull,"a",this.list,html);
			obj.style.width = "300px";
			obj.style.left = parseInt(getW(this.list)/2 - getW(obj)/2)+'px';
			obj.style.bottom = "0px";
	},

	insertFiles : function(){
		var obj = null;
		var row = null;
		var parentNode = null;

		var stack = eval("this.stack"+this.stack);
		if(this.stack == "A")this.stack = "B";else this.stack = "A";
		var stack2 = eval("this.stack"+this.stack);

		while(stack.length > 0){
			try{
				obj = stack.pop();
				parentNode = getObject('file_'+ obj['parent']+'_'+this.id);
				if( parentNode ){
					obj.depth += parentNode.data.depth;
					row = this.buildRow(obj);
					this.list.insertBefore(row,parentNode.nextSibling);
					row.className += " hide";
					parentNode.data.filLen++;
				}else{
					stack2.push(obj);
				}
			}catch( e ){  }
		}
		if(stack2.length > 0)
			this.insertFiles();
	},

	buildRow : function( data ){
		var row = document.createElement("div");
		var thisTree = this;

		row.oncontextmenu = function(e){thisTree.displayContext( data , e);return false;};

		row.id = "file_"+data.id+"_"+this.id;
		row.className = "row "+data.type+"Row";
		row.data = data;
		row.data.filLen = 0;
		row.data.expanded = false;

		for(var key in this.schema){
			row.appendChild(this.buildCell( data , key ));
		}
		row.onmouseover = function(){row.className += " highlight"};
		row.onmouseout = function(){row.className = row.className.replace(/\shighlight/gi,'');};

		if(thisTree.functions["PrepRow"]){
			eval("thisTree."+this.functions["PrepRow"]+"(row)");
		}
		return row;
	},

	buildCell : function( data , key){
		var functions = null;
		var cell = null;
		var thisTree = this;
		cell = document.createElement("div");
		cell.id = key + "_" + data.id+"_"+this.id;
		cell.className = "cell";
		cell.style.width = this.schema[key]+"%";

		if(this.settings.display == "details" || key == this.index[0]){
			if(key == this.index[0]){
				var width = (5 * data.depth);
				var offset = 0;
				var html = ''
				html +="<div class='cell wSpace' style='width:"+(width)+"%;'></div>";
				html +="<div class='cell nSpace' style='width:"+(95 - width)+"%;'>";

				if(data['type'] == 'dir')
					html +="<div id='tri_"+data.id+"_"+this.id+"' class='cell collapsedFT'></div>";

				html += "<div id='name_"+data.id+"_"+this.id+"' class='cell' style='width:90%;'>"+prepMessage(data[key],true,true)+"</div></div>";
				cell.innerHTML = html;
			}else{
				cell.innerHTML += prepMessage(data[key],true,true);
			}

			if((functions = this.functions[data['type']][key])){
				for(var name in functions){
					eval('cell.on'+name+' = function(){thisTree.'+functions[name]+'("'+data.id+'")};');
				}
				cell.className += " active";
			}
		}

		return cell;
	},

	displayIcons : function(){
		var thisTree = this;
		thisTree.openFolder(thisTree.wrkDir);
	},

	displayGallery : function(){
		var thisTree = this;
		thisTree.openFolder(thisTree.root);
	},

	displayPhotoMan : function(){
		var thisTree = this;
		thisTree.openFolder(thisTree.root);
	},

	showImage : function (fileId){
		data = this.files[fileId];
		showPhotoRemarkWindow(data);
	},

	buildIcon : function( data ){
		var html = '';
		var img = ecirkitImagesURL +"gallery_small.png";
		if(data.type != "dir"){
			img = "/api/servlets/images?photo_id="+data.id+"&format=png&width=166&height=112";
		}
		var thisTree = this;
		var temp = null;
			temp = document.createElement("div");
			temp.id = "file_" + data.id + "_"+this.id;
			temp.className = "fl oh p icon";
			var html = "<div class='iconImg'><table><tbody><tr><td align='center'><img src='"+img+"'></td></tr></tbody></table></div>";
			html += "<div id='"+this.index[0]+"_"+data.id+"_"+this.id+"' class='iconTitle'><div id='name_"+data.id+"_"+this.id+"'>"+prepMessage(data[this.index[0]],true,true,false)+"</div></div>";
			temp.innerHTML = html;

			for(var key in this.functions[data.type]["Icon"]){
				eval("temp.on"+key+" = function(){thisTree."+this.functions[data.type]["Icon"][key]+"(data.id)}");
			}

			temp.oncontextmenu = function(e){thisTree.displayContext(thisTree.files[data.id],e)};
			temp.onmouseover = function(){
				var obj = null;
				if(!(obj = getObject("FileNamePopUp"))){
					obj = createObject("div","FileNamePopUp",dhNull,getObject("canvas"));
				}
					obj.style.position = "absolute";
					obj.style.width = "auto";
					obj.style.height = "auto";
					obj.style.background = "#346896";
					obj.style.color = "white";
					obj.style.textAlign = "center";
					obj.style.zIndex = "6666";
					obj.innerHTML = prepMessage(data[thisTree.index[0]],true,true,false);
				registerTipObject(obj, 0, 25);
			};
			temp.onmouseout = unregisterToolTip;
			temp.data = data;

		if(thisTree.functions["PrepIcon"]){
			eval("thisTree."+this.functions["PrepIcon"]+"(row)");
		}
		temp.img = img;
		return temp;
	},

	buildGallery : function( data ,imgser ){
		var html = '';
		var img = "/images/themes/launch/md_folder_icon.png";
		if(data.type != "dir"){
			img = "/imgserver/"+data.id+"?photo_id="+data.id+"&format=png&size=188";
		}
		var thisTree = this;
		var temp = null;
			temp = document.createElement("div");
			temp.id = "file_" + data.id + "_"+this.id;
			temp.className = "fl oh p gallery";
			temp.style.background = "black url("+img+") center no-repeat";
			var html = "<div class='galleryImg'>"+
				((data.type == "dir") ?
					"<div class='galleryName p'>"+
					data[this.index[0]]
					+"</div>"
					: "<div class='gts active' style='position:absolute;bottom:2px;right:2px;'>"+
						'<div class="a o f bgBlack a50"></div> <div class="r">'+((data.remarksCont==null)?0:data.remarksCont)+" Remark"+((parseInt(data.remarksCont) != 1)? "s" : '' )+"</div>"
					+"</div>"
					//"<div class='gts active' style='position:absolute;bottom:2px;right:2px;'>"+
						//'<div class="a o f bgBlack a50"></div> <div class="r">'+((data.tags==null)?0:data.tags.length)+" Tag"+((parseInt(data.tags.length) != 1)? "s" : '' )+"</div>"
					//+"</div>"
				)
			+"</div>";
			temp.innerHTML = html;

			for(var key in this.functions[data.type]["Icon"]){
				eval("temp.on"+key+" = function(){thisTree."+this.functions[data.type]["Icon"][key]+"(data.id)}");
			}

			//temp.oncontextmenu = function(e){thisTree.displayContext(thisTree.files[data.id],e)};
			temp.data = data;

		if(thisTree.functions["PrepIcon"]){
			eval("thisTree."+this.functions["PrepIcon"]+"(row)");
		}
		temp.img = img;
		return temp;
	},
	
	buildPhotoIcon : function( data ){
		var html = '';
		var img = ecirkitImagesURL +"gallery.png";
		if(data.type != "dir"){
			img = "/api/servlets/images?photo_id="+data.id+"&format=png&width=188&height=130";
		}
		var thisTree = this;
		var temp = null;
			temp = document.createElement("div");
			temp.id = "file_" + data.id + "_"+this.id;
			temp.className = "fl oh p photoIcon";
			temp.style.background = "url("+img+") center no-repeat";
			var html = "<div class='photoIconImg'>"+
				((data.type == "dir") ?
					"<div class='galleryName active'>"+
					data[this.index[0]]
					+"</div>"
					: ""
				)
			+"</div>";
			temp.innerHTML = html;

			for(var key in this.functions[data.type]["Icon"]){
				eval("temp.on"+key+" = function(){thisTree."+this.functions[data.type]["Icon"][key]+"(data.id)}");
			}

			temp.oncontextmenu = function(e){thisTree.displayContext(thisTree.files[data.id],e)};
			temp.data = data;

		if(thisTree.functions["PrepIcon"]){
			eval("thisTree."+this.functions["PrepIcon"]+"(row)");
		}
		temp.img = img;
		return temp;
	},

	openFolder : function( folderId ){
		dh.$(this.list.id).purge();
		var thisTree = this;
		var thisList = this.list;
		thisList.style.background = "none";

		if(this.settings.display == "gallery"){
			this.prepGallery(folderId);
		}

		var icon = null;

		for(var key in thisTree.files){
			if(thisTree.files[key].parent == folderId){
				if(thisTree.settings.display == "gallery"){
					thisTree.list.appendChild(icon = thisTree.buildGallery(thisTree.files[key]));
					if(getAbsY(icon) - getAbsY(thisTree.list) > thisTree.list.scrollBottom){
						thisTree.list.last = key;
						break;
					}
				}else if(thisTree.settings.display == "photoMan"){
					thisTree.list.appendChild(icon = thisTree.buildPhotoIcon(thisTree.files[key]));
					if(getAbsY(icon) - getAbsY(thisTree.list) > thisTree.list.scrollBottom){
						thisTree.list.last = key;
						break;
					}
				}else{
					thisTree.list.appendChild(icon = thisTree.buildIcon(thisTree.files[key]));
				}
			}
		}
		thisTree.wrkDir = folderId;
		if(thisTree.bread){
			thisTree.bread.innerHTML = thisTree.buildBreadCrumb(folderId);
			client.addHelpBeacon("community",thisTree.bread.lastChild,'slideToggle');
		}
		unregisterToolTip();
	},

	prepGallery : function ( folderId ){
		var thisTree = this;
		var thisList = this.list;
		thisList.scrollBottom = getH(thisList);
		if(!thisList.onscroll){
			thisList.onscroll = function(){
				thisList.scrollBottom = (thisList.scrollTop + getH(thisList));
				if(thisList.scrollBottom >= (thisList.scrollHeight - (getH(thisList)*.5)))
					thisTree.printFifteenMore();
			};
		}
	},

	printFifteenMore : function ( key ){
		var start = false;
		var count = 0;

		for(key in this.files){
			if(start && (count < 15)){
				if(!this.files[key]){
					break;
				}
				if(this.files[key].parent == this.wrkDir){
					this.list.last = key;
					this.list.appendChild(this.buildGallery(this.files[key]));
					count++;
				}
			}
			if(key == this.list.last){
				start = true;
			}
			if(count == 15){
				break;
			}
		}

	},

	highlightImg : function (fileId){
		var wrapper = getObject("file_"+fileId+"_"+this.id).firstChild;
			setOpacity(wrapper,60);
			wrapper.style.backgroundColor="#ffffff";
	},

	dimImg : function (fileId){
		var wrapper = getObject("file_"+fileId+"_"+this.id).firstChild;
			setOpacity(wrapper,100);
			wrapper.style.background="none";
	},

	expand : function( folderId ){
		var parentRow = getObject("file_"+folderId+"_"+this.id);
		var img = getObject("tri_"+folderId+"_"+this.id);
		if(parentRow.data.expanded){
			parentRow.data.expanded = false;
			if(this.wrkDir == folderId){
				this.setDetailsWrkDir(this.root);
			}
			if(img){
				img.className = "cell collapsedFT";
				//img.src = ecirkitImagesURL + 'tree_collapsed.png';
			}
		}
		else{
			this.setDetailsWrkDir(folderId);
			 parentRow.data.expanded = true;
			if(img){
				img.className = "cell expandedFT";
				//img.src = ecirkitImagesURL + 'tree_expanded.png';
			}
		}


		var row = this.list.firstChild;
		while(row){
			if(row.data){
				row.className = row.className.replace(/\shide/,'');
				img = getObject("tri_"+row.data.id+"_"+this.id);
				if((row.data.parent != this.root) && !(this.files[row.data.parent].expanded)){
					if(img){
						img.className = "cell collapsedFT";
						//img.src = ecirkitImagesURL + 'tree_collapsed.png';
					}
					row.data.expanded = false;
					row.className += " hide";
				}
			}
			row = row.nextSibling;
		}
	},

	setDetailsWrkDir : function(fileId){
		var currDir = this.files[this.wrkDir];
		if(currDir){
			var obj = getObject("file_"+currDir.id+"_"+this.id);
				obj.className = obj.className.replace(/(wrkDir)|(\swrkDir)/,'');
		}
		var wrkDir = this.files[fileId];
		if(wrkDir){
			var obj = getObject("file_"+fileId+"_"+this.id);
				obj.className += " wrkDir"; 
		}
		this.wrkDir = fileId;
	},
	
	setDetailsWrkFile : function(fileId){
		var currFile = this.files[this.wrkFile];
		if(currFile){
			var obj = getObject("file_"+currFile.id+"_"+this.id);
				obj.className = obj.className.replace(/(wrkFile)|(\swrkFile)/,'');
		}
		var wrkFile = this.files[fileId];
		if(wrkFile){
			var obj = getObject("file_"+fileId+"_"+this.id);
				obj.className += " wrkFile"; 
		}
		this.wrkFile = fileId;
	},

	mkDir : function( fileId ){
		var thisTree = this;
		var list = this.list;
		var data = new Object();

		for(var key in this.schema){
			data[key] = '';
		}
		data[this.index[0]] = '<input id="newDir" name="newDir" class="fileInput" />';
		data.type = "dir";
		data.id="mkDir";
		data.parent = fileId;
		data.depth = 1;

	 	if(((fileId != this.list.id) && (this.settings.display != "icons")) || this.wrkDir != this.root){
	 		var stack = eval("this.stack"+this.stack);
			data.parent = this.wrkDir;
			data.depth += this.files[data.parent].depth;
	 		stack.push(data);
	 		this.insertFiles();
	 	}else{
	 		data.parent = this.root;
	 		var obj = null;
	 		//if(this.settings.display == "icons" || "photoMan"){
	 		//	data.parent = thisTree.wrkDir;
	 		//	obj = this.buildIcon(data);
	 		//}else{
	 			obj = this.buildRow(data);
	 		//}
			this.list.appendChild(obj);
	 	}

		var row = getObject("file_mkDir_"+this.id);
		row.className = row.className.replace(/\shide/,'');
		var input = getObject('newDir');
		input.className += " "+getObject(this.index[0]+"_mkDir_"+this.id).className;
		input.onblur = function(){
			if(input.value !=''){
				thisTree.sendMkDir(data);
			}else{
				if(row.data.parent != thisTree.root)
					thisTree.files[row.data.parent].filLen--;
				row.innerHTML = '';
				list.removeChild(row);
			}
		};
		input.onkeypress = function( e ){
			var enter = 13;
			thisTree.testKey(e , enter , data , "sendMkDir");
		};
		input.style.height = getH(input.parentNode)+"px";
		input.focus();
	},

	deleteFile : function(fileId,callback){
		var msg = '';
		var thisTree = this;
		var type = thisTree.files[fileId].type;
		if(type == "dir"){
			msg += 'This will <font style="color:red">PERMANENTLY</font>  delete this folder and all of its contents.'
					+'<br /> Are You Sure You Want To Do This?';
		}else{
			msg += 'This will <font style="color:red">PERMANENTLY</font> delete this file.'
					+'<br /> Are You Sure You Want To Do This?';
		}
		var promtp = new ePromptIt("Delete Item?", msg,
			function( response ){
				switch( response ) {
					case promptButtons.yesNo.yes:
						thisTree.sendDelete(fileId);
						break;
					case promptButtons.yesNo.no:
						break;
				}
			},
			promptButtons.yesNo,
			promptThemes.question);
	},

	sendDelete : function (fileId){
		var thisTree = this;
		var row = getObject("file_"+fileId+"_"+this.id);
		var action = "removeFolder";
		if(thisTree.files[fileId].type != "dir") action = "removeFile";
		var data = {
			action:action,
			fileId:fileId
		};
	 	this.ajax.post(this.processor,data,
	 		function( conn ){
	 			if(conn.responseObject["Error"]){
	 				client.userError("Error",conn.responseObject["Error"]);
	 				return false;
	 			}
				
				if(conn.responseObject && conn.responseObject[0] && conn.responseObject[0][thisTree.index[0]]){
					thisTree.indexFiles(conn.responseObject);
					thisTree.fullRefresh();
					thisTree.wrkDir = thisTree.root;
				}else{
		 			thisTree.loadFiles();
				}
	 		},
	 		null,thisTree.settings.window);
	},

	renameFile : function( fileId ){
		var thisTree = this;
		var cell = getObject("name_"+fileId+"_"+this.id);
		var className = getObject("file_"+fileId+"_"+this.id).className;
		var className = "fileInput "+getObject(this.index[0]+"_"+fileId+"_"+this.id).className;
		var input = document.createElement('input');

		input.id = "input_"+fileId+"_"+this.id;
		input.className = className + ' borderWh';
		input.value = cell.innerHTML;
		input.onkeypress = function(e){thisTree.testKey(e , 13, fileId, "sendRename")};

		cell.oriHTML = cell.innerHTML;
		cell.innerHTML = "";
		cell.appendChild(input);

		input.onblur = function(){cell.innerHTML = cell.oriHTML};
		input.style.height = getH(input.parentNode)+"px";
		input.focus();
	},

	moveFolder : function( fileId ){
		this.buildMoveFolder( fileId );
	},

	sendMkDir : function( data ){
		var input = getObject("newDir");
		var thisTree = this;
		data[this.index[0]] = input.value;
		data["value"] = input.value;
		data["action"] = "newFolder";
		input.value = '';
	 	this.ajax.post(this.processor,data,
	 		function( conn ){
	 			input.onblur();
	 			data = conn.responseObject;
	 			if(data["Error"]){
	 				client.userError("Error",data["Error"]);
	 				return;
	 			}else{
					thisTree.loadFiles();
	 			}
	 		},
	 		null,thisTree.settings.window);
	},

	sendRename : function( fileId ){
		var cell = getObject("name_"+fileId+"_"+this.id);
		var thisTree = this;
		var value = (!getObject("vaultRenameFolder"))? getObject("input_"+fileId+"_"+this.id).value : getObject("vaultRenameFolder").value;
		var data = {
			action:"renameFolder",
			fileId:fileId,
			value:value,
			parent:thisTree.files[fileId].parent
		};
	 	this.ajax.post(this.processor,data,
	 		function( conn ){
	 			if(conn.responseObject["Error"]){
	 				cell.innerHTML = cell.oriHTML;
	 				client.userError("Error",conn.responseObject["Error"]);
	 				return;
	 			}
	 			cell.innerHTML = value;
	 		},
	 		null);
	},

	sendMove : function ( fileId ){
		var thisTree = this;
		var newParent = getObject('moveSelect').value;
		var action = "moveFolder";
		if(newParent == thisTree.root){
			var parentName = "root";
		}else{
			var parentName = this.files[newParent][this.index[0]];
		}
		if(thisTree.files[fileId].type != "dir") action = "moveFile";
		var data = {
			action:action,
			fileId:fileId,
			value:this.files[fileId][this.index[0]],
			parent:newParent,
			parentName: parentName
		};
		thisTree.destroyHTML(getObject('moveDiv'));
	 	this.ajax.post(this.processor,data,
	 		function( conn ){
	 			if(conn.responseObject["Error"]){
	 				client.userError("Error",conn.responseObject["Error"]);
	 				return false;
	 			}
	 			thisTree.loadFiles();
	 		},
	 		null,thisTree.settings.window);
	},

	testKey : function( e , key, data, action){
		if(!e) e = window.event;
		if((e.keyCode || e.which) == key) {
			eval("this."+action+"( data );");
			return false;
		}
	},

	viewIcons : function(){
		this.loadFiles();
		this.settings.display = "icons";
		this.settings.header = false;
		this.refresh();
	},

	viewDetails : function(){
		this.settings.display = "details";
		this.settings.header = true;
		this.loadFiles();
	},


	viewList : function(){
		this.settings.display = "list";
		this.settings.header = false;
		this.loadFiles();
	},

	viewGrid : function(){
		this.loadFiles();
		this.settings.display = "grid";
	},

	view : function( as ){
		this.loadFiles();
		this.settings.display = as;
		this.refresh();
	},

	remarkPopUp : function( fileId ){
		var obj = null;
		this.highlightImg(fileId);
		
		if(!(obj = getObject("urlPopUp"))){
			obj = createObject("div","urlPopUp",dhNull,getObject("canvas"));
		}
		var data = this.files[fileId].remark;
		if(!data)return;
		var html = 	'<div>'+data.displayName+' said:</div>'+
					'<div>'+prepMessage(data.message,true,true,false)+'</div>'+
					'<div>at '+prepDate(data.dateCreated)+'</div>';
		obj.innerHTML = html;
		registerTipObject(obj, -68, 25);
	},
	
	remarkPopDown : function( fileId ){
		this.dimImg(fileId);
		unregisterToolTip();
	},

	displayContext : function( data , e){
		var temp = null;
		var thisTree = this;
		var menu;
		if(!e) var e = window.event;
		dh.stopEvent(e);
		if(!(menu = getObject('tree_context'))){
			menu = document.createElement("div");
			menu.id = 'tree_context';
			document.body.appendChild(menu);
			document.onclick = function(){menu.innerHTML = '';menu.style.display = "none";};
			delete dh.nodes['tree_context'];
			dh.addObject('tree_context',none);
		}

		dh.$('tree_context').moveTo(dh.mouseX,dh.mouseY);
		dh.$('tree_context').bringToFront();
		menu.id = 'tree_context';
		menu.style.display = "block";
		menu.innerHTML = '';
		menu.className = "context";

		for(var id in this.context[data.type]){
			temp = document.createElement("div");
			temp.id = "context_"+id+"_"+this.id;
			temp.className = "contextRow p borderWh";
			temp.innerHTML = id;
			temp.onmouseover = Function('getObject(\''+temp.id+'\').className += " highlight"');
			temp.onmouseout = Function("getObject(\""+temp.id+"\").className = getObject(\""+temp.id+"\").className.replace(/\\shighlight/,\"\");");
			menu.appendChild(temp);
			var func = 'getObject(\''+temp.id+'\').onclick = function(){thisTree.'+this.context[data.type][id]+'(\''+data.id+'\')};';
			eval(func);
		}
	},

	displayDetails : function (fileId){
		var detailsDiv = null;
		var data = getObject("file_"+fileId+"_"+this.id).data;

		if(!(detailsDiv = getObject('detailsDiv'))){
			detailsDiv = document.createElement('div');
			detailsDiv.id = 'detailsDiv';
			detailsDiv.className = 'filePop';
			if(this.settings.window){
				getObject("windowspace").appendChild(detailsDiv);
			}else{
				this.pane.appendChild(detailsDiv);
			}
			dh.addObject(detailsDiv.id,draggable);
		}else{
			detailsDiv.className = detailsDiv.className.replace(/\shide/,'');
			detailsDiv.className = detailsDiv.className.replace(/hide/,'');
		}
		var dhDetails = dh.$(detailsDiv.id);
		var html = "<div class='filePopTitleBar'>File Details";
		html += "<div class = 'close a active' onclick='getObject(\"detailsDiv\").className += \" hide\";'>";
		html += "Close</div></div>";
		html += '<div class="filePopContentWrapper">';
		html += '<div class="singleRowWrapper">'+
						'<div class="rowLabel">Location: </div>'+
						'<div class="rowContent">'+this.ancestoryObj(data.id).string+'</div>'+
				'</div>';
		for(key in this.files[fileId]){
			html += '<div class="singleRowWrapper">'+
						'<div class="rowLabel">'+key+': </div>';
			var text = '';
			if((text = this.files[fileId][key]) == '')
				text = "-";
			html +=		'<div class="rowContent"> '+text+' </div>'+
					'</div>';
		}
		html += "</div>";

		detailsDiv.innerHTML = html;
		dhDetails.centerViewport();
		dhDetails.bringToFront();
	},

	buildMoveFolder : function ( fileId ){//ancAry , fileToMove ){
		var thisTree = this;
		var title = createObject("div",dhNull,"filePopTitleBar",dhNull,"Move Wizard");
		var content = createObject("div",dhNull,"filePopContentWrapper",dhNull,'');

		var header = createObject("div",dhNull,"singleRowWrapper",content,"<h2>"+prepMessage(this.ancestoryObj(fileId).string,true,true,false)+"</h2>");

		var selectRow = createObject("div",dhNull,"singleRowWrapper",content,"");
		var selectLabel = createObject("div",dhNull,"rowLabel",selectRow,"Move To: ");
		var selectContent = createObject("div",dhNull,"rowContent",selectRow,"");

		selectContent.appendChild(this.buildFileSelect(fileId,'moveSelect'));

		createObject("div",dhNull,"filePopFooter",content,"<input type='button' id='moveSubmit' value='Submit' />   <input type='button' id='moveCancel' value='Cancel' />");

		var moveDiv = null;
		if((moveDiv = getObject('moveDiv'))){
			thisTree.destroyHTML(moveDiv);
			moveDiv = null;
		}
		moveDiv = createObject("div","moveDiv","filePop",getObject("windowspace"),'');
		moveDiv.appendChild(title);
		moveDiv.appendChild(content);

		getObject('moveCancel').onclick	= function(){
			thisTree.destroyHTML(moveDiv);
		};

		getObject('moveSubmit').onclick = function(){
			thisTree.sendMove(fileId);
		};

		var dhMove = dh.addObject(moveDiv.id,draggable);
			dhMove.centerViewport();
			dhMove.bringToFront();
	},

	buildFileSelect : function(fileId , id , setName){
		var stack = this.getDirStack();
		var data = this.files[fileId];
		var fileToMove = this.ancestoryObj(fileId);
		var ancAry = this.createAncAry(stack,fileToMove);
		var select = document.createElement("select");
			select.id = id;
			select.name = (isEmpty(setName))? id: setName;
		var root = document.createElement("option");
			root.innerHTML = "Home";
			root.value = this.root;
			select.appendChild(root);
			for(var key in ancAry){
				var option = document.createElement("option");
				option.innerHTML = prepMessage(ancAry[key]['string'],true,true,false);
				option.value = ancAry[key]['fileId'];
				if(data && (ancAry[key]['fileId'] == data.parent)){
					option.selected = true;
				}
				select.appendChild(option);
			}
		return select;
	},

	getDirStack : function(){
		var stack = new ObjStack();

		for(key in this.files){
			var data = this.files[key];
			if(data.type == "dir")
				stack.push(data);
		}
		return stack;
	},

	createAncAry : function( stack , fileToMove ){
		var ary = new Array();
		while(stack.length){
			var data = stack.pop();
			var file = this.ancestoryObj(data.id);

			if((file.string.search(eval("/"+fileToMove.string+".*/")) == -1) || (fileToMove.string == "Home")|| data.type != "dir"){
				ary.push(file);
			}
		}
		ary.sort(this.byString);

		return ary;
	},

	ancestoryObj : function ( fileId ){
		var data = this.files[fileId];
		var ary = new Array();
		parentList = '';
		if(data){
			parentList = data[this.index[0]];
			while(data.parent != this.root){
				parentList = this.files[data.parent][this.index[0]]+"->"+parentList;
				ary.unshift(data.parent);
				data = this.files[data.parent];
			}
		}
		if(parentList !=''){
			parentList = "Home->"+parentList;
		}else{
			parentList = "Home";
		}

		ary.unshift(this.root);
		var file = {
				'string' : parentList,
				'fileId' : fileId,
				'ary'	 : ary
			};
		return file;
	},

	byString : function (a , b){
		if(a['string'] < b['string'])
			return -1;
		if(a['string'] > b['string'])
			return 1;
		if(a['string'] == b['string'])
			return 0;
	},

	__resize : function(){
		var list = getObject(this.id+"_list");
		var thisTree = getObject(this.id).tree;
		var temp = list;
		var paneH = dh.$(thisTree.id).getH();
		var paneW = dh.$(thisTree.id).getW();
		var offsetH = 0;

		if(temp){temp = temp.previousSibling;}

		if(thisTree.settings.sideBar){temp = temp.previousSibling;}

		while(temp){
			offsetH += getH(temp);
			temp = temp.previousSibling;
		}
		getObject(this.id+"_list").style.height = (paneH - offsetH)+"px";

		if(thisTree.settings.sideBar){
			thisTree.list.style.width = thisTree.resizeSideBar((paneH - offsetH),paneW)+"px";
		}
	},

	destroyNestedHTML : function( obj ){
		var limit = obj.childNodes.length;
		var temp = null;
		for(var x = 0; x < limit ; x++){
			temp = obj.firstChild;
			this.destroyNestedHTML( temp );
		}
		this.destroyHTML( obj );
	},

	destroyHTML : function( obj ){
		var id = obj.id;
		obj.innerHTML = '';
		obj.parentNode.removeChild(obj);
		try{delete dh.nodes[id];}catch(e){  }
		obj = null;
	}
}
// end of FileTree.prototype
/**************************************
 * Client-side management
 **************************************/
var client;
function ClientObject(){

	window.onbeforeunload = function () {
 		return "This action will leave eCirkit. Are you sure you want to continue?";
	};

	dh.addResizeEvent('resizeWindow',
		function () {
			client.__resize();
		}
	);


	if( !this.soundLibrary ){
		var libDiv = createObject('div', '', '', getObject('header'));
		createFlash( libDiv, '/flash/sounds.swf', 'soundLibrary', 1 , 1, true );
		this.soundLibrary = getObject('soundLibrary');
	}

}
ClientObject.prototype = {
	//-------------------------
	//	Data
	//-------------------------
	data:
		{
			avatarDetails:[]
		},

	//dynamic data
	nameSpaces:			{},
	windows: 			{},
	windowSettings:		{},
	windowFunctions:	{},
	remoteFunctions : 	{},
	helpBeacons : 		{},

	//window positions and states
	webtopMemory:		false,
	communityMemory:	false,

	//layer related
	currentLayer:		'',
	webtopVisible:		false,
	communityVisible: 	true,
	cirkitvisionVisible:false,
	contestsVisible:	false,

	//contest related
	currentContest:		'',
	contests:			{},

	//user related
	loggedInID:			-1,
	viewUserID:			-1,

	//windows
	cascadeCount: 		0,
	cascadeStep:		30,
	windowCount:		0,

	//user settings
	paneOpacity:		100,
	dragOpacity:		70,
	windowOpacity:		100,
	matteOpacity :		30,

	//GUI variables
	workingElement: 	null,
	windowXPadding:		3,
	windowYPadding:		3,
	borderWidth : 		3,
	waitingForDetails: 	false,
	viewingDetails:		false,

	//-------------------------
	// Incoming Events
	//-------------------------
	__resize : function (){

		//var preLoad = createObject( 'img', dhNull, 'vh', canvasStorage);
		//preLoad.onload = function () { client.setBackground(); deleteObject(preLoad); };
		//preLoad.src = this.getBrowseUserBGSrc();

		if( this.currentLayer == 'cirkitvision' ){
			H( getObject('windowspace'), dh.viewportH - dh.nodes.header.h);
			dh.nodes.cirkitvision.resizeTo( dh.viewportW, dh.viewportH );

			//client.autosizeCirkitvision();

			//setBackground( 'windowspace', "#000000", this.getCirkitvisionSrc(),  'center', 'center', 'no-repeat' );
		}
	},

	//-------------------------
	// Custom Events
	//-------------------------
	onSwitchUser : null,
	invoke : function (ev){
		try{
			return this['on' + ev]();
		} catch (ex){  }
		return true;
	},

	/****************************
		Style Switching
	****************************/
	includeCss : function (cssFile) {

		try{

			if( cssFile.indexOf("http://") < 0) cssFile = "http://" + window.document.domain + cssFile;

			//prevent file from being added twice
			for (var i = 0; i < document.styleSheets.length; i++){
				var currentSheet = document.styleSheets[i];
				if( currentSheet.href == cssFile ) {
					return currentSheet;
				}
			}

			var htmlDoc = document.getElementsByTagName('head').item(0);
			var css = document.createElement('link');
			css.setAttribute('rel', 'stylesheet');
			css.setAttribute('type', 'text/css');
			css.setAttribute('href', cssFile);
			htmlDoc.appendChild(css);

			css.disabled = true;
		}
		catch(e){
			return false;
		}
		return css;

	},

	//-------------------------
	// Data / Client-Server actions
	//-------------------------
	initContest : function( contestName , callback ){

		if( !dh.nodes.mainContent ){
			dh.addObject('mainContent',		none);
			dh.addObject('mainContentUpper',none);

			//console.trace();
			//if we're here then no user was loaded to display yet.
			//since we're ready we should do that now?
			//this might be causing issued on first load.
			this.setViewUser( this.getBrowseUserID() );
			//hmm aybe not. leavign it off for now.
		}


		//prevent attempts to enable a 'null' contest
		if( contestName == dhNull ) return;

		//get the css with an ajax request to cache.
		var cssElem = this.includeCss('/css/contests/' + contestName + '.css');

		//get the contest's javascript
		if( !client.contests[contestName] ){
			ajax.post(
				'/api/servlets/script',
				{
					type: 'contests',
					name: contestName
				},
				function( connectionInstance ){
					if( connectionInstance.serverResponse ){
						var retVal = true;
						try{
							var contest = eval(connectionInstance.serverResponse);
						} catch (ex){
							retVal = false;
						}

						//callback ourself on a new thread to continue the init process
						if( retVal ){
							setTimeout( function(){ client.initContest( contestName, callback ) } , 0);
						}
					}
				},
				function ( connectionInstance ){
					client.userError(nameSpace+" Error", "Could not download "+nameSpace+" script, aborting. Please try again.");
				}
			);

			//exit here, if the scripts download properly,
			//this function will be run again. when they get here
			//return false so the caller knows to exit and wait.
			return false;
		}

		//make sure we're not trying to load the same contest again


		//contest data object storage
		var contest = this.contests[this.currentContest];

		//remove the old contest is ther was one and it wasnt the new one.
		if( this.currentContest != contestName) {

			if( this.currentContest != ''){
				contest = this.contests[this.currentContest];
				this.currentCss.disabled = true;
				contest.removeContest();
			}

			//get the new contest
			contest = this.contests[contestName];

			cssElem.disabled = false;

			//call the contest's init handler if it's got one.
			if( contest.initContest() ) {
				contest.initContest();
			}

		}

		setBackground(
			getObject('windowspace'),
			"#000000",
			((contest.bgSrc) ? contest.bgSrc : "" ),
			((contest.bgPosX) ? contest.bgPosX : "center" ),
			((contest.bgPosY) ? contest.bgPosY : "top" ),
			"no-repeat"
		);

		//setBackground( 'windowspace', "#000000", '',  '', '', '' );
		setBackground( 'header', "#000000", '',  '', '', '' );

		//remember the contest we've got loaded here.
		this.currentContest = contestName;
		this.currentCss = cssElem;

		//we're done, call the callback.
		if( callback ){
			callback();
		}

	},

	switchStyleSheets : function (page, theme){

		page = page.toLowerCase();
		theme = theme.toLowerCase();

		var existing = false;

		var global = 		cssPath + 'css/global.css';
		var profile = 		cssPath + 'css/profile.css';
		var t_global = 		cssPath + 'css/' + theme + '/global.css'
		var t_page = 		cssPath + 'css/' + theme + '/' + page + '.css'
		var t_ie_global = 	cssPath + 'css/' + theme + '/ie_global.css';
		var t_ie_page = 	cssPath + 'css/' + theme + '/ie_' + page + '.css';


		includeCss( t_global );
		includeCss( t_page );
		if ( dh.ie ){
			includeCss( t_ie_global );
			includeCss( t_ie_page );
		}

		//disable unnecessary
		for (var i = 0; i < document.styleSheets.length; i++){
			var currentSheet = document.styleSheets[i];
			if( currentSheet.href != global &&
				currentSheet.href != profile &&
				currentSheet.href != t_global &&
				currentSheet.href != t_page &&
				currentSheet.href != t_ie_global &&
				currentSheet.href != t_ie_page ) {
				currentSheet.disabled = true;
			}
		}

		themes.selectTheme(page, theme);
	},


	//-------------------------
	// Data / Client-Server actions
	//-------------------------
	initNameSpace : function( nameSpace, folder, callback){
		if( !client.nameSpaces[nameSpace] ){
			ajax.post(
				'/api/servlets/script',
				{
					type: folder,
					name: nameSpace
				},
				function( connectionInstance ){
					if( connectionInstance.serverResponse ){
						var space = eval(connectionInstance.serverResponse);
						if(space.init){space.init();}
						if(callback)
							setTimeout(callback, 0);
					}
				},
				function ( connectionInstance ){
					client.userError(nameSpace+" Error", "Could not download "+nameSpace+" script, aborting. Please try again.");
				}
			);

			//exit here, if the scripts download properly,
			//this function will be run again. when they get here
			// return false so the caller knows to exit and wait.
			return false;
		}
	},

	remoteCallback : function( type, status ){
		var data = {type:type,status:status};
		for(key in this.remoteFunctions){
			client.remoteFunctions[key](data);
		}
	},

	//-------------------------------------------------
	//Header Bar Features
	//-------------------------------------------------
	quickAvatarUpload : function( input ){
		var form = getObject('quickAvatarUploadForm')
		client.prompt = new ePromptIt(	'Avatar Upload',
						'You\'ve Selected "'+input.value+'" to Upload As Your Avatar. Is This OK?',
						function( resp ){
							switch(resp){
								case promptButtons.yesNo.yes :
									//form.submit();
									startUpload('','quickAvatarUploadForm');
									client.remoteFunctions['quickSaveAvatar'] = function(){

										client.userInfo(function(){
											client.initWindow("myPhotos",function(){
												if(!client.windowFunctions.myPhotos.formArea){
													client.windowFunctions.myPhotos.onFetch = function(){this.setEditPhoto(-1);};
												}else{
													client.windowFunctions.myPhotos.onFetch = function(){
														this.setEditFolder(this.root);
														this.setEditPhoto(-1);
													};
													client.windowFunctions.myPhotos.fetchWindowData();
													client.windows.myPhotos.show();
												}
											});

										});
										delete client.remoteFunctions['quickSaveAvatar'];
									}
									break;
								case promptButtons.yesNo.no :
									form.removeChild(form.lastChild);
									form.innerHTML += '<input type="file" id="quickAvatarUpload" name="quickAvatarUpload" class="a fv a0" onchange="client.quickAvatarUpload(this);" />';
									break;
							}
						},
						promptButtons.yesNo,
						promptThemes.question);
	},

	saveAvatar : function (input){
		var form = createObject("form","quickAvatarUpload",'a o',dh.nodes.loggedInAs);


	},

	//turns on a mini menu item by adding a style
	turnOnMiniMenuItem : function( element ){
		if(element.obj.className.indexOf(element.id + '_on') == -1 ) element.obj.className += ' ' + element.id + '_on';
	},
	//turns off a mini menu item by removing a style
	turnOffMiniMenuItem : function( element ){
		var reg = eval("/(\\s" + element.id + "_on)|(" + element.id + "_on)/");
		element.obj.className = element.obj.className.replace( reg , '');
	},


	//-------------------------
	// Window Related Methods
	//-------------------------
	addWindow: function( windowID, settingsObject, windowParent, windowTitle ){
		if( !this.windows[windowID] ){
			this.windows[windowID] = new DHWindow(windowID, settingsObject, windowParent, windowTitle);
			this.windowCount++;
			return this.windows[windowID];
		} else{
			//window already exists
		}
		return false;
	},

	initWindow : function ( windowName , callback){

		if( client.windows[windowName] ) {
			//login test here
			if( client.windows[windowName].visible == false &&
				parseInt(client.windowSettings[windowName].securityLevel) == windowSecurity.secured &&
				client.isLoggedIn() == false ){
				//this is so the stack can drop back and the login and then open our window process can continue
				//seperately until they either log in or cancel
				setTimeout("client.login_logout(true, function( response ){ if(response == 'success') client.windows['"+ windowName +"'].show(); } );", 100);
				return false;
			}

			if(callback)callback();

			return true;
		}

		//if( recursing == dhNull ) recursing = false;
		//get window config
		if( !client.windowSettings[windowName] ){
			ajax.post(
				'/api/processors/windowProcessor',
				{
					type : 'getWindowConfig',
					window_id : windowName
				},
				function( connectionInstance ){
					if( connectionInstance.responseObject ){
						client.windowSettings[ connectionInstance.requestObject.window_id ] = connectionInstance.responseObject;
						setTimeout(function(){client.initWindow(  connectionInstance.requestObject.window_id , callback );}, 0);
					} else {
						
					}
				},
				function ( connectionInstance ){
					client.userError("Window Error", "Could not download window config, aborting. Please try again.");
				}
			);

			//exit here, if the settings download properly,
			//this function will be run again. when they get here
			// return false so the caller knows to exit and wait.
			return false;
		}

		//login test here
		if( parseInt(client.windowSettings[windowName].securityLevel) == windowSecurity.secured && client.isLoggedIn() == false ){
			//this is so the stack can drop back and the login and then open our window process can continue
			//seperately until they either log in or cancel
			setTimeout(
				function(){
					client.login_logout(
						true,
						function( response ){
							client.loginResponse(
								response,
								windowName,
								callback
							);
						}
					);
				},
				0
			);
			return false;
		}

		//get window scripts
		if( !client.windowFunctions[windowName] ){
			ajax.post(
				'/api/servlets/script',
				{
					type: 'window',
					name: windowName
				},
				function( connectionInstance ){
					if( connectionInstance.serverResponse ){
						eval(connectionInstance.serverResponse);
						setTimeout(function(){client.initWindow( connectionInstance.requestObject.name , callback ); }, 0);
					}
				},
				function ( connectionInstance ){
					client.userError("Window Error", "Could not download window script, aborting. Please try again.");
				}
			);

			//exit here, if the scripts download properly,
			//this function will be run again. when they get here
			// return false so the caller knows to exit and wait.
			return false;
		}

		//now that we have the settings and functions. and we're logged in. create the window.
		if( !client.windows[windowName] ){
			client.windowFunctions[windowName].init( callback );
			client.addHelpBeacon( 'webtop', client.windows[windowName].windowNode.obj, client.windows[windowName].id);
			client.windows[windowName].onBringToFront = function(){client.currentWindow = this;}

		}
		//the only way this was called was when it was asked to appear
		//so if we're ready, go for it
		client.windows[windowName].show();
		if(callback)callback();
	},

	rememberWindow : function ( windowName ){

		var sourceData = null;
		if( this.currentLayer == 'webtop' ) sourceData = this.webtopMemory;
		if( this.currentLayer == 'community' ) sourceData = this.communityMemory;

		if( sourceData )  {
			if( sourceData[ windowName ] ){
				return sourceData[ windowName ];
			}
		}

		return false;
	},

	setCascadePosition: function ( windowToPosition ){
		this.cascadeCount++;
		if(this.cascadeCount == 7) this.cascadeCount = 1;
		var x = dh.scrollLeft + (this.cascadeStep * this.cascadeCount );
		var y = dh.scrollTop + dh.nodes.header.h + (this.cascadeStep * this.cascadeCount);
		windowToPosition.windowNode.moveTo(x, y);
		windowToPosition.normalPosition = [ x , y ];
		windowToPosition.__drop();
	},

	hideSecuredWindows: function ( windowToPosition ){
		for( var windowName in this.windows ){
			if (this.windows[windowName].securityLevel > windowSecurity.unsecured) this.windows[windowName].hideNow();
		}
	},

	//-------------------------------------------------
	//User Related Conditionals
	//-------------------------------------------------
	isHomeProfile: function(){
		return (this.getUserID() == this.getBrowseUserID());
	},
	isContestProfile : function (){
		return ! ( isEmpty( this.getBrowseUserObject().user_configuration.contestName ) );
	},

	isLoggedIn : function (){
		return (this.loggedInID != -1);
	},

	myProfile : function (){
		if( !this.isLoggedIn() ){
			this.login_logout( true ,
				function ( res ) {
					if(res == 'success'){
						client.myProfile();
					}
				}
			);
			return;
		}

		if( this.getBrowseUserID() != this.loggedInID ) {
			this.browseUser( this.loggedInID );
		} else {
			this.openLayer( 'community' );
		}
	},

	login_logout : function( action , optionalCallback ){
		//don't preform an action, just make sure the login
		// logout out button is right

		//true is used an the action for both log in and log out,
		//since it is technically a toggle action
		// that, and i added in the cancel action later on. look in the failure area
		if( action == true ){
			if(this.isLoggedIn()){
				var log = this.loggedInID;
				var brow = this.getBrowseUserID();

				//log out
				logout();

			} else {
				this.showWorkspaceMatte();
				if( optionalCallback ) this.windows.login.optionalCallback = optionalCallback;
				this.windows.login.show();
			}
			return;
		}

		//some after we login / logout checks
		if( this.isLoggedIn() ){

			//if the login window is up, we're waiting for SOMETHING
			if( this.windows.login.visible ){

				//resume any pending ajax requests
				//and allow ajax operation
				ajax.resume();

				this.windows.login.__close();

				//try to callback after logout
				if( this.windows.login.optionalCallback ) {
					try{
						this.windows.login.optionalCallback( 'success' );
						delete this.windows.login['optionalCallback'];
					} catch( ex) {
						
					}
				}

				//reload the profile for manager links if necessary
				if( this.loggedInID == this.getBrowseUserID() )
					this.setViewUser( this.getBrowseUserID() );
			}

			//update the log in / log out button
			var d = new Date();
			var uniqueId = 107 + d.getTime().toString().substr(6, 10);
			var html =	'<img src="/api/servlets/images?blop='+uniqueId+'&type=avatar&user_id='+this.loggedInID+'&size=41" width="41" height="41" />'+
						'<form class="a o f" name="quickAvatarUploadForm" action="/api/processors/upload?type=quickSaveAvatar" id="quickAvatarUploadForm" target="remoteIFrame" enctype="multipart/form-data" method="post">' +
						'<input type="hidden" name="AJAX_UPLOAD" id="AJAX_UPLOAD" value="1" />' +
						'<input type="hidden" name="APC_UPLOAD_PROGRESS" id="progress_key" value="' + uniqueId + '" />' +
							'<input type="file" id="quickAvatarUpload" name="quickAvatarUpload" class="a fv a0" onchange="client.quickAvatarUpload(this);" />'+
						'</form>';
			dh.nodes.loggedInAs.write('<strong>' + this.data.userInfo.profile_info.display_name + '</strong>\'s Toolbar.<a href="#" onclick="client.login_logout(true); return false;" class="logout">LOG OUT</a>');
			dh.nodes.loggedInAsAvatar.write(html);
			window.uniqueId = uniqueId;
			
			//dh.nodes.login.write("Log Out");

		//login failed or was cancelled
		} else {
			/*
			//if the login window is up, we're waiting for SOMETHING
			if( this.windows.login.visible ){
				//close the login window, which in turn closes the matte if its open
				//client.windows.login.__close();

				//try to callback after logout
				if( this.windows.login.optionalCallback ){
					try{
						//if the action was to cancel send a cancel, otherwise send failure?
						//we could also put in a check for multiplke log in attmepts here
						this.windows.login.optionalCallback( ( action == 'cancel' ) ? 'cancel' : 'failure' );
						delete this.windows.login['optionalCallback'];
					} catch( ex) {
						//firebugDebug( "client.login_logout (234): ", ex );
					}
				}
			}

			//hide all secured windows
			this.hideSecuredWindows();

			if(this.currentLayer == 'community' ){
				//reload the profile we're on if it's ours. to remove admin links.
				if( log == brow ) this.setViewUser( );
			} else {
				this.openLayer('community');
			}

			//update the log in / log out button
			dh.nodes.loggedInAs.write("<strong>You are not logged in.</strong><a href='#' onclick='client.login_logout(true); return false;' class='logout'>LOG IN</a>");
			dh.nodes.loggedInAsAvatar.write('');
			//dh.nodes.login.write("Log In");
			*/
		}
	},

	loginResponse : function( response, windowName ,callback){
		switch( response ){
			case 'success':
				this.initWindow( windowName ,callback);
				break;
			case 'cancel':
				client.userError("Cannot open window", "The window you are typing to open requires a login. Please log in to open this window.");
				break;
			case 'failure':
				client.userError("Cannot open window", "The window you are typing to open requires a login. Please log in to open this window.");
				break;
			default:
				break;
		}
	},

	inactivityPromptResponse : function ( response ){

		switch ( response ) {
			case promptButtons.timeoutButtons.login:

				//if logiun successful then we will just resume the ajax requets
				client.login_logout( true );

				break;
			case promptButtons.timeoutButtons.nothing:

				//reset any ajax info we had
				ajax.clear();

				//allow new requests again
				ajax.resume();

				//switch to a default view
				this.openLayer('community');

				break;
			case promptButtons.timeoutButtons.splash:

				//ignore all ajax requests because they are useless now
				splash();
				break;
			default:

				break;
		}

	},

	processError : function ( errObj ){
		switch( errObj.error ){
			case '417':

				ajax.pause();

				//timed out
				try{
					//function ePromptIt( title, caption, callback, buttons, theme, timeout ){
					var ep = new ePromptIt(
						"Not logged in",
						"You are not logged in. You may have been logged out due to inactivity. What would you like to do?",
						function(response){client.inactivityPromptResponse(response); },
						promptButtons.timeoutButtons,
						promptThemes.question
					);

					//client.userNotice(  );
				} catch (ex){
					alert(ex);
				}

				break;
			case '6675':
				//errObj = {};
				throw "perms";
				break;
			default:
				break;
		}
	},

	//-------------------------------------------------
	//UserID Functions
	//-------------------------------------------------
	getUserID: function(){
		return this.loggedInID;
	},

	getBrowseUserID: function(){
	 	if( this.viewUserID == this.loggedInID ||
			this.viewUserID == -1){
			return this.loggedInID;
		}else {
			return this.viewUserID;
		}
	},

	//-------------------------------------------------
	//User Related Data
	//-------------------------------------------------
	getLoggedInUserObject: function(){
		return (this.data.userInfo) ? this.data.userInfo : false;
	},

	getBrowseUserObject: function(){
	 	if( this.isHomeProfile() ){
			return this.data.userInfo;
		}else {
			return this.data.viewUserInfo;
		}
	},
	getBrowseUserDetails: function(){
	 	return this.getBrowseUserObject().user_details;
	},

	getBrowseUserInterests: function(){
	 	return this.getBrowseUserObject().user_interests;
	},

	getBrowseUserProfile: function(){
		return this.getBrowseUserObject().profile_info;
	},

	getBGSrc : function ( userInfoObject ) {
	/*
		var src = (userInfoObject.user_configuration.bgImg != 0 ) ?
					"/api/servlets/images?photo_id=" + userInfoObject.user_configuration.bgImg:
					"/images/themes/launch/bg.jpg";
	*/
		var src = (userInfoObject.user_configuration.bgImg != 0 ) ?
					"/api/servlets/images?photo_id=" + userInfoObject.user_configuration.bgImg:
					"";

		//static
		return src;

		//auto size
		//return "/api/servlets/images?photo_id=" + info.user_configuration.bgImg + "&width=" + dh.viewportW + "&height=" + dh.viewportH;
	},

	//-------------------------------------------------
	//User Related Methods
	//-------------------------------------------------
	updateUserInfo : function(flag){
		var date = new Date();
		var milli = date.getMilliseconds();
		var html =	'<img src="/imgserver/'+window.uniqueId+'?type=avatar&user_id='+client.loggedInID+'&size=41&milli='+milli+'" width="41" height="41" />'+
					'<form class="a o f" name="quickAvatarUploadForm" action="/api/processors/upload?type=quickSaveAvatar" id="quickAvatarUploadForm" target="remoteIFrame" enctype="multipart/form-data" method="post">' +
					'<input type="hidden" name="AJAX_UPLOAD" id="AJAX_UPLOAD" value="1" />' +
					'<input type="hidden" name="APC_UPLOAD_PROGRESS" id="progress_key" value="' + window.uniqueId + '" />' +
						'<input type="file" id="quickAvatarUpload" name="quickAvatarUpload" class="a fv a0" onchange="client.quickAvatarUpload(this);" />'+
					'</form>';

		dh.nodes.loggedInAsAvatar.obj.innerHTML = '';
		dh.nodes.loggedInAsAvatar.write(html);
		dh.nodes.loggedInAs.write("<strong>" + this.data.userInfo.profile_info.display_name + '</strong>\'s Toolbar.<a href="#" onclick="client.login_logout(true); return false;" class="logout">LOG OUT</a>');
		try{
			if(client.isHomeProfile()){
				client.setBackground(null);
				client.data["viewUserInfo"] = client.data["userInfo"];
			}
			if(!flag){
				client.windows.avatar.show();
			}
		}catch(ex){console.log(ex)}
	},
	
	userInfo : function ( callback ,flag,win){
			ajax.post( '/api/processors/user',
				{
					type : 'userInfo',
					i: client.loggedInID
				},
				function (connectionInstance){
					if( connectionInstance.responseObject ){
						client.data["userInfo"] = connectionInstance.responseObject;
						client.loggedInID = client.data["userInfo"].profile_info.user_id;

						client.updateUserInfo(flag);
					} else {
						return false;
					}
					if(callback){
						callback();
					}
				},
				function (connectionInstance){
				}
			);
	},

	//this function can be tiggered anywhere it will download the settings and load em when it can.
	//you can continue seperately. and the callback will be triggered at the end of all of it.
	initUserWindowSettings : function ( callback ){

		//don;t load the settings if we won't have any
		if( !client.isLoggedIn() ) return false;

		if( !client.webtopMemory && !client.communityMemory ){

			ajax.post(
				'/api/processors/windowProcessor',
				{
					type : "getAllWindowSettings"
				},
				function (connectionInstance){
					if( connectionInstance.responseObject ){
						client.webtopMemory = connectionInstance.responseObject['webtop'];
						client.communityMemory = connectionInstance.responseObject['community'];

					} else if( connectionInstance.serverResponse == 'false' ) {
						client.webtopMemory = {"myMail":{"window_name":"myMail","x":(parseInt((dh.viewportW/2) - (850/2))),"y":"0","w":"850","h":"437","visibility":"1","helpVisible":"1"}};
					} else {
						client.userError("WebTop Error", "Your window settings could not be loaded.");

						//prevent infinite loop if the windows settings don't load.
						return false;
					}

					client.initUserWindowSettings( callback );
				},
				function (connectionInstance){
					client.userError("WebTop Error", "Your WebTop settings could not be loaded.");
				}
			);
			//tell the parent function to exit, we'll use the callback from here
			return false;

		//the data is here
		//so do something with it now.
		} else {

			//since the data just came down the pipe, if we'reo n onle of the layers
			//open the layers settings
			var userData = false;
			if( client.currentLayer == 'webtop' ) userData = client.webtopMemory;
			if( client.currentLayer == 'community' ) userData = client.communityMemory;
			if( userData )this.openLayerMemory( userData );

			//we're done.
			if( callback ) callback();
		}

		//we're successful
		return true;
	},

	browseUser: function( viewUserID ){
		if( this.viewUserID != viewUserID ){

			ajax.post( '/api/processors/user',
				{
					type : 'userInfo',
					i : viewUserID
				},
				function (connectionInstance){
					if( connectionInstance.responseObject ){
						client.data.viewUserInfo = connectionInstance.responseObject;

						if(client.windows['photoViewer']&&client.windows['photoViewer'].visible){
							client.windows['photoViewer'].__close();
						}

						client.setViewUser( viewUserID );
					} else {
						return false;
					}
				},
				function (connectionInstance){

				},
				client.windows.avatar
			);
		}
		//call back after the ajax request
		/*
		} else {

			this.setViewUser(viewUserID);

		}
		*/
	},

	setViewUser: function( viewUserID ){

		if ( !this.invoke( 'SwitchUser' ) ) return;

		client.quietCommunity();

		if( ( viewUserID != dhNull) ) client.viewUserID = parseInt( viewUserID );

		if( this.isHomeProfile() ){ getObject('myProfile').className='hover'; }
		else { getObject('myProfile').className=''; }

		client.remarksloaded = false;

		try{delete client.data.profileRemarks;}
		catch (nope){}

		try{delete client.data.contestRemarks; }
		catch (nope){}

		var browseUser = this.getBrowseUserObject();

		if( browseUser.user_configuration.contestName ) {

			var cName = browseUser.user_configuration.contestName;

			this.openLayer('contest_profile');

			//load the contest javascript
			this.initContest( cName, function (){ showRemarks( true ); } );

			//this.windows.windshield.__tab("remarks");
			//this.windows.windshield.invoke("Reload");

		} else {
			//open the community layer if we need to.
			if( !dh.nodes.community.visible ){
				//open layer will also set the bg, since this is the first load.
				this.openLayer('community');
			} else {
				//set the bg if we're only switching users
				this.setBackground();
			}

			dh.nodes.profileTagLine.write( browseUser.profile_info.tag_line  );
			dh.nodes.profileUserName.write( browseUser.profile_info.display_name +' <font style="font-size:14px;font-family:Arial,Helvetica,sans-serif;font-weight:bold;">' +browseUser.user_configuration.profileViews+ " Views</font>" );

			//load some data
			setTimeout(function(){client.windows.avatar.show()					},0);
			setTimeout(function(){client.windows.windshield.invoke("Reload");	},0);
			setTimeout(function(){client.windows.profile_contacts.show()		},0);
			setTimeout(function(){client.windows.carousel.show()				},0);
			//client.windows.profileMusic.show();
		}

		setTimeout(function(){client.windows.profileMusic.show()			},0);

	},

	//-------------------------------------------------
	// Front-end Features
	//-------------------------------------------------
	menuTip : function ( srcElement, tip ){
		clearTimeout( client.menuTipTimeoutRef );

		var menuCallout = getObject('menuCallout');
		X( menuCallout ,
			getAbsX(srcElement) -
				(
					( getW(menuCallout) - getW(srcElement) )
				/ 2
				)
		);
		Y( menuCallout , dh.scrollTop + 100 )
		var menuCalloutCaption = getObject('menuCalloutCaption');
		menuCalloutCaption.innerHTML = tip;

		showObject(menuCallout);
	},

	closeMenuTip : function (){
		client.menuTipTimeoutRef = setTimeout( client.menuTipTimeout , 250 );
	},

	menuTipTimeout : function (){
		invisible( getObject( 'menuCallout' ));
	},

	showPopupMenu : function ( menuData , x , y ){

		if( x == dhNull ) x = dh.mouseX;
		if( y == dhNull ) y = dh.mouseY;

		var content = '';
		for(var menuItem in menuData){
			var itemData = menuData[menuItem];
			content += '<div class="popupMenuItem" onmouseover="this.className=\'popupMenuItem menuItemHover\';" onmouseout="this.className=\'popupMenuItem\';" onmousedown="'+ itemData.callback +'"><div class="menuIcon '+ menuItem +'Icon"></div><div class="menuText">'+ itemData.caption +'</div></div>';
		}

		var menu = dh.nodes.popupMenu;

		menu.X( x );
		menu.Y( y );

		menu.showBlock();

		var canvas = getObject('popupMenu_canvas');
		var borderWidth = 2;
		X( canvas, borderWidth );
		Y( canvas, borderWidth );

		canvas.style.width = 'auto';
		canvas.style.height = 'auto';
		canvas.innerHTML = content;

		W(canvas, getW(canvas) + (borderWidth * 2) + 15);
		H(canvas, getH(canvas) + (borderWidth * 2));

		//hmm.
		dh.addMouseDownEvent( 'menuFocus', function (){ client.hidePopupMenu(); return true; } );

		menu.resizeTo(getW(canvas) + (borderWidth * 2), getH(canvas) );
		menu.show();
		//var menuCanvas = getObject('');
	},

	hidePopupMenu : function (){
		dh.removeMouseDownEvent( 'menuFocus' );
		dh.nodes.popupMenu.hide();
	},

	initAvatarDetails : function (user_id, srcElement) {
		if (this.data.avatarDetails[user_id] != null) { client.showAvatarDetails(user_id, srcElement);	} //stored data?
		else{
			ajax.post(
				'/api/processors/avatarDetails',
				{
					userid: user_id
				},
				function(connectionInstance){
					connectionInstance.decode()
					client.data.avatarDetails[user_id] = connectionInstance.responseObject[0]; //store our new data
					if(client.waitingForDetails == user_id ) { client.showAvatarDetails(user_id, srcElement); } //display the data if we're still waiting
				},
				function(connectionInstance){

				}
			);
	   	}
	},

	avatarDetailsTimeout : function (){
		return	function () {
				client.avatarDetailsTimeoutRef =
					setTimeout(
						function(){ client.hideAvatarDetails() }, 0);
				client.waitingForDetails = 0;
			};
	},

	showAvatarDetails : function (userID, srcElement) { //aD = avatarDetails

			//display the pop;up
			if(client.waitingForDetails != userID) return;

			var aD = client.data.avatarDetails[userID];

			if (aD.userName.length > 15){ aD.userName = aD.userName.substring(0, 14) + '...'; }

			var avatarDetails = getObject('avatarDetails');
			var avatarDetailContent = getObject('avatarDetailContent');
			var detailContent = '';

			detailContent += '<div class="a detailsAvatar"><img src="'+ getAvatarURL(userID) +'"width="85" height="85" /></div>';
			detailContent += '<div class="a detailsUserName">'+ aD.userName+'</div>';
			detailContent += '<div class="a detailsLastLogin"><span class="tinyLabel">Last Login:</span> '+ aD.lastLogin+'</div>';
			detailContent += '<div class="a detailsJoined"><span class="tinyLabel">Joined:</span> '+aD.createDate+'</div>';
			detailContent += '<input type="text" class="a detailsURL" onclick="this.select();" onkeypress="return false;" value="www.ecirkit.com/'+( (aD.urlName) ? aD.urlName : 'user/' + userID )+'" />';
			detailContent += '<div class="a detailsBio">';

			if( aD.age && aD.sex  ){
				detailContent += '<span class="tinyLabel">Age / Sex:</span> ' + aD.age + aD.sex;
			} else if (aD.age){
				detailContent += '<span class="tinyLabel">Age</span> ' + aD.age;
			} else if (aD.sex){
				detailContent += '<span class="tinyLabel">Sex</span> ' + aD.sex;
			}
			if( aD.location  ){
				detailContent += '<br/><span class="tinyLabel">Location:</span> ' + aD.location;
			}
			if( aD.userInterests  ){
				if (aD.userInterests.length > 150){ aD.userInterests = aD.userInterests.substring(0,147) + '...'; }
				detailContent += '<br/><span class="tinyLabel">Interests:</span> ' + aD.userInterests;
			}

			detailContent += '</div>';

			detailContent += '<div class="a detailsControls">';
				detailContent += '<div class="a detailsControl remarkButton"></div>';
				detailContent += '<div class="a detailsControl contactRequestButton" ></div>';
				detailContent += '<div class="a detailsControl sendMailButton" ></div>';
				detailContent += '<div class="a detailsControl vaultRequestButton" ></div>';
				detailContent += '<div class="a detailsControl imButton" ></div>';
			detailContent += '</div>';

			avatarDetailContent.innerHTML = detailContent;

			/*
			 * this might be unnecessary
			 * client.waitingForDetails = false;
			 * client.viewingDetails = userID;
			 */

			//point to this point.
			var x,y;

			if( srcElement ){
				x = (getAbsX(srcElement) + (getW(srcElement) / 2) - 142);
				y = getAbsY(srcElement) + (getH(srcElement) / 2) - 44;
			} else {
				x = dh.mouseX;
				y = dh.mouseY - 44;
			}

			var detailsHeight = 390;
			var detailsVisibleHeight = 350;
			var detailsWidth = 266;

			//test y visibility
			if( y - detailsVisibleHeight > dh.scrollTop + dh.nodes.header.h ){
				y -= (detailsHeight);
				avatarDetails.className = 'a alwaysOnTop above';
			} else {
				y += 88;
				avatarDetails.className = 'a alwaysOnTop below';
			}

			X( avatarDetails, x);
			Y( avatarDetails, y);

			if( dh.dragObject ) return;

			showObject(avatarDetails);
	},

	hideAvatarDetails : function( userID ){
		//if(this.waitingForDetails == userID){ this.waitingForDetails = false; } //not any more
		//if(!this.viewingDetails) return; //nothing to hide we shouldn't even be here
		//if(this.viewingDetails != userID) return; //dont hide another avatar info

		hideObject(getObject('avatarDetails'));
		this.viewingDetails = false;
	},

	setBackground : function ( forceURL , win){
		var bg;
		var bgColor;
		var bgRepeat;
		var info = {};
		var header = getObject("header");

		if( this.currentLayer == 'community' ){
			info = client.getBrowseUserObject();
		} else {
			info = client.getLoggedInUserObject();
		}

		if( forceURL ) {
			bg = forceURL;
			bgColor = "#000000";
			bgRepeat = "no-repeat";
		} else if(info){
			bg = this.getBGSrc(info);
			bgColor = info.user_configuration['bgColor'];
			bgRepeat = (info.user_configuration["bgStyle"] == 'centered') ? "no-repeat" : "repeat";
		} else {
			//bgRepeat = "no-repeat";
			//bg = "/images/themes/launch/bg.jpg";
		}

		if(bg){
			header.style.backgroundImage = "url(" + bg + ")";
			document.body.style.backgroundImage = "url(" + bg + ")";
			/*var img = new Image();
			if(win){
				img.onload = function(){
					win.setLoading(false);
				}
				img.src = bg;
				win.setLoading(true);
				if(img.complete){
					win.setLoading(false);
				}
			}*/

		} else {
			header.style.backgroundImage = "none";
			document.body.style.backgroundImage = "none";
		}

		if (!bgColor){ bgColor = "#FFFFFF"; }
		header.style.backgroundColor = bgColor;
		document.body.style.backgroundColor = bgColor;


		if( bgRepeat ){
			header.style.backgroundRepeat = bgRepeat;
			document.body.style.backgroundRepeat = bgRepeat;
		}

	},

	enableScrolling : function (){
		enableScrolling(dh.docBody);
		dh.removeScrollEvent('noscroll');
	},

	disableScrolling : function(){
		disableScrolling(dh.docBody);
		dh.addScrollEvent('noscroll', function () { document.body.parentNode.scrollTop = 0; } );
	},

	highlightDropZones : function (){

		for( var dzID in dh.dropZones ){
			var dz = dh.dropZones[dzID];
			var tmpHighlight = getObject('dzHighlight' + dzID);
			if( !tmpHighlight ){
				tmpHighlight = createObject( 'div', 'dzHighlight' + dzID, 'dropZoneHighlight dragSpace', 'canvas');
			}
			tmpHighlight.style.left = 	dz.getAbsX() + 'px';
			tmpHighlight.style.top = 	dz.getAbsY() + 'px';
			tmpHighlight.style.width = 	dz.w + 'px';
			tmpHighlight.style.height = dz.h + 'px';
		}

	},

	dimDropZones : function (){
		for( var dzID in dh.dropZones ){
			var dz = dh.dropZones[dzID];
			var tmpHighlight = getObject('dzHighlight' + dzID);
			if( !tmpHighlight ){
				tmpHighlight.outterHTML = '';
			}
		}
	},

	flashDropZones : function (){

	},

	//---------------------------
	// Help Mode
	//---------------------------
	addHelpBeacon : function ( layerName, HTMLElement, helpKey){
		if ( !client.helpBeacons[ layerName ]) client.helpBeacons[layerName] = {};

		HTMLElement.helpKey = helpKey;

		var arBeacons = client.helpBeacons[layerName];
		if( HTMLElement.id == '')
			return false;
		arBeacons[HTMLElement.id] = HTMLElement;
	},

	__help : function (){

		var beaconContainer = getObject('helpBeacons');
		var beaconsOverLay = getObject('helpBeaconsOverLay');
		var helpTip = getObject('helpTip');

		if( !beaconContainer ){
			//get the list of visible beacons

			var helpBeacons = client.helpBeacons[this.currentLayer ];
			var halfWidth = 0;

			//only continue if we have any beacons
			if( !helpBeacons ){
				return; //nothing to do.....ever
			}

			beaconsMatte = createObject('div', 'helpBeaconsMatte', 'a o f', getObject('canvas') );
			H(beaconsMatte,document.body.parentNode.scrollHeight);

			beaconsOverLay = createObject('div', 'helpBeaconsOverLay', 'a o f', getObject('canvas') );
			H(beaconsOverLay,document.body.parentNode.scrollHeight);

			beaconContainer = createObject('div', 'helpBeacons', 'a o f', getObject('canvas') );
			H(beaconContainer,document.body.parentNode.scrollHeight);
			beaconContainer.onclick = function (){ client.__help(); return true;  };
			beaconContainer.style.cursor= "url(/images/help.cur),pointer";

			var helpTipHTML = 	'<img class="a o"  src="/images/helptip.png">'+
								'<div class="a contentCanvas" style="top:0px">'+
									'<div class="beaconHelpInfoLoading contentCanvas"></div>'+
									'<div class="beaconHelpInfoTitle"></div>'+
									'<div class="beaconHelpInfoInfo"></div>'+
								'</div>';
			helpTip = createObject('div', 'helpTip', 'helpTip a', getObject('canvas'), helpTipHTML);
			registerTipObject(helpTip, 26, 26);
			helpTip.style.zIndex = 18002;

			var topOffset = getAbsY(beaconContainer);

			//go through our list and build some beacons
			for( var i in helpBeacons){
				var thisBeacon = helpBeacons[i]
				if(!isVisible(thisBeacon) )continue;

				var tmpOverlay = createObject('div', 'helpOverlay_'+i, 'a helpOverlay', beaconsOverLay );
				var tmpBeacon = createObject('div', 'helpBeacon_'+i, 'a helpBeacon', beaconContainer );

				//read the beacon size on the first build
				if(!halfWidth) halfWidth = getW( tmpBeacon ) / 2;

				//move it and center it
				X(tmpBeacon, getAbsX(thisBeacon) - halfWidth);
				Y(tmpBeacon, getAbsY(thisBeacon) - halfWidth - topOffset + thisBeacon.scrollTop);

				tmpBeacon.onmouseover = Function('getObject("helpOverlay_'+i+'").style.background="orange";this.over = true;client.fetchHelpInfo("'+thisBeacon.id+'")');
				tmpBeacon.onmouseout = Function('this.over = false;getObject("helpOverlay_'+i+'").style.background="none";getObject("helpTip").firstChild.src = "/images/helptip.png";hideObject(getObject("helpTip").childNodes[1]);');
				//tmpBeacon.style.zIndex = thisBeacon.style.zIndex + 1;

				X(tmpOverlay, getAbsX(thisBeacon));
				Y(tmpOverlay, getAbsY(thisBeacon) - topOffset + thisBeacon.scrollTop);
				W(tmpOverlay,getW(thisBeacon));
				H(tmpOverlay,getH(thisBeacon));
				//tmpOverlay.style.zIndex = thisBeacon.style.zIndex + 1;
			}
			//dh.nodes.workspaceMatte.resizeTo( dh.viewportW, dh.documentH - dh.nodes.header.h );
		} else {

			//if we are here then __help was calledb y the callback from closeing the global matte
			//just remove the beacons, the matte will close itself.
			//beaconContainer.innerHTML = "";

			//remove the element too.
			deleteObject(beaconContainer);
			deleteObject(beaconsMatte);
			deleteObject(beaconsOverLay);
			unregisterToolTip();
			deleteObject(helpTip);
		}

	},

	fetchHelpInfo : function( id ){
		if(!client.beaconInfo)client.beaconInfo = {};
		if(!getObject("helpBeacon_"+id) || !getObject("helpBeacon_"+id).over) return;
		var helpTip = getObject("helpTip");

		helpTip.childNodes[0].src = '/images/help.png';
		helpTip.childNodes[1].childNodes[1].innerHTML = 'Loading';
		helpTip.childNodes[1].childNodes[2].innerHTML = '';
		showObject(helpTip.childNodes[1]);
		showObject(helpTip.childNodes[1].childNodes[0]);
		if(!client.beaconInfo[getObject(id).helpKey]){
			ajax.post(
				'/api/processors/user',
				{type : 'getBeacon',id : getObject(id).helpKey},
				function( connectionInstance ){
					if( connectionInstance.responseObject ){
						client.beaconInfo[getObject(id).helpKey] = connectionInstance.responseObject;
					}else{
						client.beaconInfo[getObject(id).helpKey] = {id:'-1',title:getObject(id).helpKey,info:"Sorry, help is on it's way!"};
					}
					setTimeout("client.fetchHelpInfo('"+id+"')",0);
				});

			return false;
		}else{
			helpTip.childNodes[1].childNodes[1].innerHTML = client.beaconInfo[getObject(id).helpKey].title;
			helpTip.childNodes[1].childNodes[2].innerHTML = client.beaconInfo[getObject(id).helpKey].info;
			if(client.beaconInfo[getObject(id).helpKey].id == "-1")delete client.beaconInfo[getObject(id).helpKey];
			hideObject(helpTip.childNodes[1].childNodes[0]);
		}
	},


	//---------------------------
	// Prompts and popups
	//---------------------------
	userNotice : function ( title, caption , callback  ){
		var ep = new ePromptIt( title, caption, callback, null, promptThemes.notice, 	3500);
	},
	userWarning : function ( title, caption , callback  ){
		var ep = new ePromptIt( title, caption, callback, null, promptThemes.warning, 	3500);
	},
	userError : function ( title, caption , callback ){
		var ep = new ePromptIt( title, caption, callback, null, promptThemes.error, 	3500);
	},

	//---------------------------
	// Mattes and shadows
	//---------------------------
	showGlobalMatte : function ( theme, clickToExit, exitCallback ) {
		var globalMatte = getObject('globalMatte');

		if( !globalMatte ){
			globalMatte = createObject('div', 'globalMatte', dhNull, getObject('canvas'), dhNull);
			setOpacity( globalMatte, client.matteOpacity );
		}

		globalMatte.className = 'a o alwaysOnTop ' + ( (theme == dhNull) ? 'matteDefault' : theme );

		if( clickToExit ) globalMatte.onmousedown = function(){ client.closeMatte(); };
		if(exitCallback) globalMatte.exitCallback = exitCallback;

		W(globalMatte, dh.viewportW);
		H(globalMatte, dh.documentH );

		showObject(globalMatte);
	},

	showWorkspaceMatte : function ( theme, clickToExit, exitCallback ){

		var workspaceMatte = getObject('workspaceMatte');
		var headerBGMatte = getObject('headerBGMatte');

		if( !workspaceMatte ){
			workspaceMatte = createObject('div', 'workspaceMatte', dhNull,  dh.nodes.windowspace.obj , dhNull);
			setOpacity( workspaceMatte, client.matteOpacity );
			setOpacity( headerBGMatte, 	client.matteOpacity );
		}

		workspaceMatte.className = 'a o alwaysOnTop ' + ( (theme == dhNull) ? 	'matteDefault' : theme );
		headerBGMatte.className = 	'a o alwaysOnTop ' + ( (theme == dhNull) ? 	'matteDefault' : theme );
		if( clickToExit ) workspaceMatte.onmousedown = function(){  client.closeMatte(); };
		if(exitCallback) workspaceMatte.exitCallback = exitCallback;

		W(workspaceMatte, dh.viewportW);
		H(workspaceMatte, dh.documentH - dh.nodes.header.h );

		W(headerBGMatte, dh.viewportW);
		H(headerBGMatte, dh.nodes.header.h );

		showObject(workspaceMatte);
		showObject(headerBGMatte);

	},

	closeMatte : function (){
		var globalMatte = getObject('globalMatte');
		if( globalMatte ) {
			if(globalMatte.exitCallback)
			if( !globalMatte.exitCallback() ) return;
			globalMatte.exitCallback = null;
			hideObject(globalMatte);
			globalMatte.className = 'a o matteDefault';
		}

		var workspaceMatte = getObject('workspaceMatte');
		if( workspaceMatte ) {
			if(workspaceMatte.exitCallback)
			if( !workspaceMatte.exitCallback() ) return;
			workspaceMatte.exitCallback = null;
			var headerBGMatte = getObject('headerBGMatte');
			hideObject(workspaceMatte);
			hideObject(headerBGMatte);
			workspaceMatte.className = 'a o matteDefault';
			headerBGMatte.className = 'a o matteDefault';
		}
	},


	/* *****************************************
	 * Layer Related Client stuffs From here on out
	 * *****************************************/
	openLayer : function( layer, callback ){

		//are we switching to the webtop specifically?
		//and do we need to log in?
		//the webtop is the only layer that requires login
		if( layer == 'webtop' && !this.isLoggedIn() ){
			this.login_logout(
				true,
				function( response ){
					//console.log("response - " + response);
					if( response == 'success' ){
						//console.log('opening webtop after login. b.');
						openLayer('webtop');
					}
				}
			);
			return;
		}

		//if nothing changed, just exit
		if( layer == this.currentLayer) return;

		//turn off the exiting layer
		switch( this.currentLayer ){
			case 'webtop':
				dh.nodes.header.obj.background = 'transparent none 0px 0px fixed repeat';
				this.hideWebtop();
				break;
			case 'community':
				this.hideCommunity();
				break;
			case 'cirkitvision':
				//showBlock( getObject( 'windowspace' ) );
				enableScrolling ( dh.nodes.cirkitvision.obj );
				showObject(getObject('header'));
				resetBackground( 'header' );
				resetBackground( 'windowspace' );
				getObject('windowspace').style.height = 'auto';
				dh.nodes.cirkitvision.hide();
				deleteObject( this.cirkitvisionPlayer );
				delete this.cirkitvisionPlayer;
				break;
			case 'contests':
				dh.nodes.contests.hide();
				client.turnOffMiniMenuItem(dh.nodes.layers_contests );
				break;
			case 'contest_profile':
				this.hideContestProfile();
				break;
			default:
				break;
		}

		//make sure we're switching to the right kind of community layer.
		if( layer == 'community' ){

			var userInfo = this.getBrowseUserObject();
			if( userInfo.user_configuration.contestName ){
				layer = 'contest_profile';


				//forace the bg reload here
				//this.initContest (this.currentContest);
			}
		}
		//set our new layer
		this.currentLayer = layer;

		//show the new layer
		switch(layer) {
			case 'webtop':
				//opening the webtop is a large process
				this.showWebtop();

				//change menu hightlights
				getObject('myProfile').className = '';

				//set the webtop background (loggedin user's bg)
				this.setBackground();

				break;
			case 'community':

				//show the community layer
				this.showCommunity();

				//myprofile highlight
				if( this.isHomeProfile() ){ getObject('myProfile').className='hover'; }
				else { getObject('myProfile').className=''; }

				//show the viewuser's bg
				//there is another line that sets the BG in setViewUser 846 area
				this.setBackground();

				if(playing >= 0)
					playVideo(playing);

				break;
			case 'cirkitvision':

				//change menu hightlights
				getObject('myProfile').className='';
				//client.turnOnMiniMenuItem( dh.nodes.layers_cirkitvision );

				//get out cirkitvision layer up on the screen, and the size of the screen
				dh.nodes.cirkitvision.resizeTo( dh.viewportW, dh.viewportH );
				dh.nodes.cirkitvision.show();

				//hide header
				hideObject(getObject('header'));

				//show our media player bg
				setBackground( 'header', "", "/images/spacer.gif", "transparent" );
				disableScrolling ( dh.nodes.cirkitvision.obj );
				H( getObject('windowspace'), dh.viewportH - dh.nodes.header.h);

				//IF NO FLASH PLAYER EXISTS THEN MAKE ONE! YAY!
				if( !this.cirkitvisionPlayer ){
					this.initCirkitvision();
				}

				break;
			case 'contests':

				//change menu hightlights
				getObject('myProfile').className = '';

				client.turnOnMiniMenuItem( dh.nodes.layers_contests );

				if( !this.data.contests ){
					this.fetchContests();
				}

				//show the contests layer.
				dh.nodes.contests.show();

				//show the logged in user's bg
				this.setBackground();

				break;
			case 'contest_profile':

				//change menu hightlights
				getObject('myProfile').className='';

				this.showContestProfile();

				break;
			default:
				break;
		}

		//if( callback ){
		//	callback();
		//}

		//we switced something
		return true;
	   //119785 - level 16 in bloxorz
	}, //end of openLayer


	openLayerMemory : function ( data ){

		//prepare our windows on screen
		for( var windowIndex in data ){

			//window
			var workingWindow = this.windows[windowIndex];
			var workingData = data[windowIndex];

			var windowName = workingData.windowName;

			if( workingWindow ) workingWindow.useWindowProcessor = false;

			//do we need to show it?
			if( parseInt( workingData.visibility ) == 1){

				if (!workingWindow) {
					client.initWindow(windowIndex);
					//exit here, the window should look for it's settings if it needs them before it shows
					//this needs to be added
					continue;
				}

				if( workingData.x && workingData.y)
					workingWindow.windowNode.moveTo( parseInt( workingData.x ) ,  parseInt( workingData.y ) );

				if( workingData.h && workingData.w)
					workingWindow.windowNode.resizeTo( parseInt( workingData.w ) ,parseInt( workingData.h ) );

				if(parseInt( workingData.helpVisible ) ){
					workingWindow.helpCanvas.obj.firstChild.innerHTML = '<div class="r fh tac">'+windowIndex + ' Help</div><div class="p" style="background:transparent url(/images/themes/skin1/window_controls.png) repeat scroll -13px -33px;height:14px;width:14px;position:absolute;right:0px;top:0px;" onclick="client.windows.'+windowIndex+'.__help();"></div>';
					workingWindow.helpCanvas.obj.lastChild.innerHTML = client.windowSettings[windowIndex].helpText;
					workingWindow.helpCanvas.show();
				}


				//we have to use show incase something was reiszed
				if( !workingWindow.visible) workingWindow.show();

				//finally set any window states?
				//console.log(workingWindow.windowState);
				//console.log(workingData.windowState);
				if( workingWindow.windowState != workingData.windowState ){
					workingWindow.setWindowState(workingData.windowState);
				}
			//do we need to hide it?
			} else {

				//was the window initialized
				if( !workingWindow ){
					//skip it, it's hidden by settings and hasn't been initialized yet anyway
					continue;
				}

				//hide it if it's there and visible
				if(workingWindow.visible) workingWindow.hide();
			}

			workingWindow.useWindowProcessor = true;
		}

	},

	//------------------------------------
	// Webtop
	//------------------------------------
	//this is meant to be called by toggle layer
	//so make sure you never call this yourself
	showWebtop : function(){

		//download the data if we need to. then resume
		//if( !this.initUserWindowSettings( function(){ client.showWebtop(); } ) ) return;
		//this was made a little more independent
		this.initUserWindowSettings();

		//rememeber the user settings
		var webTopData = client.webtopMemory;
		this.openLayerMemory(webTopData);

		this.webtopVisible = true;
		client.turnOnMiniMenuItem( dh.nodes.layers_webtop );
	},

	hideWebtop : function (){
		this.hideSecuredWindows();
		this.webtopVisible = false;
		client.turnOffMiniMenuItem( dh.nodes.layers_webtop );
	},

	//------------------------------------
	// Community
	//------------------------------------
	initCommunity : function (){

		if( !client.windows.avatar ){
			dh.addObject("profileUserName",	none);
			dh.addObject("profileTagLine",	none);
			dh.addObject("profile_column1", none);
			dh.addObject("profile_column2", none);
			dh.addObject("profile_row1", 	none);
			dh.addObject("profile_row2", 	none);

			initLeaveRemark();
			initProfileAvatar();
			initProfileMusic();
			initProfileWindshield();
			initProfileContacts();
			initCarousel();

			//needs to be here for a logged in user switching to the community layer
			//if( this.viewUserID == -1 && this.getUserID() > 0 )
			this.setViewUser( this.getBrowseUserID() );
			//hmm aybe not. leavign it off for now.

		}
	},

	showCommunity : function (){
		//show the communtiy layer
		dh.nodes.community.show();

		//initialize all of it's child windows if necessary
		this.initCommunity();

		//download the data if we need to. then resume
		//we're doing this last so the windows aren;t loading at the same time as a profile.
		//if( !this.initUserWindowSettings( function(){ client.showCommunity(); } ) ) return;
		//this used to tbe the method above. i made it a little more independant
		this.initUserWindowSettings();

		this.communityVisible = true;
		this.turnOnMiniMenuItem( dh.nodes.layers_community );

	},

	hideCommunity : function (){

		this.lastUserProfile = this.getBrowseUserID();
		dh.nodes.community.hide();

		//for( var windowName in this.windows ){
		//	if (this.windows[windowName].securityLevel > windowSecurity.unsecured) this.windows[windowName].hideNow();
		//}

		this.communityVisible = false;
		this.turnOffMiniMenuItem(dh.nodes.layers_community );

		this.quietCommunity();

	},

	//cleans up any playing flash objects.
	quietCommunity : function (){

		// clear out the Video content on the profile so that the video
		// won't continue playing (audio can still be heard)
		clearProfileVideoContent();

		//shush the remarks too.
		stopRemarksFlash();
	},

	//------------------------------------
	// Contest Profile
	//------------------------------------
	showContestProfile : function ( ){

		//show the contests layer.
		dh.nodes.contest_profile.show();

		//initialize all of it's child windows if necessary
		this.initContest();

		this.turnOnMiniMenuItem( dh.nodes.layers_community );
		//the contest bg will be set when it's done being initialized

	},
	hideContestProfile : function ( ){
		//resetBackground('windowspace');
		resetBackground( 'header' );
		resetBackground( 'windowspace' );
		dh.nodes.contest_profile.hide();
		client.turnOffMiniMenuItem(dh.nodes.layers_community );
	},
	//cleans up any playing flash objects.
	quietContestProfile : function ( ){

		// clear out the Video content on the profile so that the video
		// won't continue playing (audio can still be heard)
		//clearProfileVideoContent();

		//shush the remarks too.
		//stopRemarksFlash();
	},

	//------------------------------------
	// Contests Layer
	//------------------------------------
	fetchContests : function ( forceReload ) {

		//delete any existing data
		if( forceReload ) delete this.data.contests;

		//exit if already loaded
		if( this.data.contests ) return;

		ajax.post(
			'/api/processors/contests',
			{
			},
			function (connectionInstance){
				if( connectionInstance.responseObject ){
					client.data.contests = connectionInstance.responseObject;
					client.drawContests();
				}
			},
			function (connectionInstance){
			}
		);
	},

	drawContests : function (){
		var contestContainer = getObject('contests');
		var cardColumn = 'card1';

		for( var a = 0 ; a < this.data.contests.length; a++){
			var tmpContest = this.data.contests[a];

			cardColumn = 'card' + ((a % 2) + 1);

			var card = createObject('div', dhNull, 'fl contestCard ' + cardColumn, contestContainer);
				var cardLeft = 	createObject('div', dhNull, 'fl fv cardLeft', card);

					var statusImage = "";
					if( tmpContest.winnerUserID > 0 ){
						statusImage = "winner";
					}else if( false ){
						//this will be used for the case where the contest has ended and no winner has prevailed
						statusImage = "enter";
					}else {
						statusImage = "enter";
					}

					//winner / enter now
					var status = 		createObject('div', dhNull, 'fl fh mt5', cardLeft);
						H( status, 35 );
						status.style.background =  "url(/images/contests/"+statusImage+".png)";

					var winnerIcon = 	createObject('div', dhNull, 'fl fh gtm p', cardLeft);
						H( winnerIcon, 110 );
						winnerIcon.style.background = 'url(/images/contests/'+tmpContest.shortName+'/winner.png)';
						winnerIcon.onclick = Function( "client.browseUser( " + tmpContest.winnerUserID + " ); ");

					var userInfo = "";

					if( parseInt(tmpContest.winnerUserID) > 0 ) {

						if (tmpContest.winnerUserName){
							userInfo += '<span class="gtl">'+tmpContest.winnerUserName+'</span><br/>';
						}

						if (tmpContest.winnerLocation){
							userInfo += '<span class="gtm">'+tmpContest.winnerLocation+'</span><br/>';
						}

						if (tmpContest.winnerVideo){
							userInfo += '<span class="gtm p cG" onclick="client.openVideo( getPageRootURL() + \''+tmpContest.winnerVideo+'\')">Watch the video</span><br/>';
						}

					} else {
						userInfo = '<span class="gtl mt5">This could be you!</span>';
					}

					var winnerInfo = 	createObject('div', dhNull, 'fl fh cWhite tac b', cardLeft, userInfo);

				var cardRight = createObject('div', dhNull, 'fr fv cardRight p', card);
				cardRight.style.background = "url(/images/contests/" + tmpContest.shortName + "/card.jpg)";
				cardRight.onclick = Function( "client.browseUser( " + tmpContest.contestUserID + " ); ");
		}
	},

	//--------------------------
	// Cirkitvision Layer
	//--------------------------
	initCirkitvision : function ( callback ){

		//switch layers is necessary
		if( this.currentLayer != 'cirkitvision' ){
			this.openLayer(	'cirkitvision' );

			if( callback ){
				this.cirkitvisionCallback = callback;
			}
			//open layer will call this function if no plash pklayer exists
			//so exit now
			return false;
		}

		//do we have the video player ready?
		if(!this.cirkitvisionPlayer){
			///console.log('a');
			var playerSize = this.getCirkitvisionSize();

			//add the video player
			createFlash(  getObject( 'cirkitvision_x' ), '/flash/cirkitvision.swf', 'cirkitvisionPlayer', playerSize[0], playerSize[1] , true, '', true );

			this.autosizeCirkitvision();

			//save a reference, we need to talk to it later
			this.cirkitvisionPlayer = getObject('cirkitvisionPlayer');

			if( callback ){
				this.cirkitvisionCallback = callback;
			}

			//parent function must exit
			return false;
		} else if(callback){
			//re-refernce the player?
			this.cirkitvisionPlayer = getObject('cirkitvisionPlayer');

			//the flah player is loaded and ready, might as well call the callbck.
			//the callback will only be accessible as 'callback' the first time around
			//thats why i'm testing for it in this case
			callback();
		}

		//at this point this function was triggered by the last
		//line in the Flash Player witch calls this function as
		//a callback, so call our saved callback if we got one.
		//most likely, this will send a url to the flashplayer.
		if( this.cirkitvisionCallback ){

			//call it
			this.cirkitvisionCallback();

			//remove the callback, it should only be called once.
			delete this.cirkitvisionCallback;
		}
	},

	autosizeCirkitvision : function(){
		var playerSize = this.getCirkitvisionSize();

		if( this.cirkitvisionPlayer ){
			W(this.cirkitvisionPlayer, playerSize[0])
			H(this.cirkitvisionPlayer, playerSize[1])
		}

		//if( playerSize[0] > dh.viewportW ){
			X( getObject( 'cirkitvision_x' ), ( dh.viewportW - playerSize[0] ) / 2 );
		//}

		Y(getObject( 'cirkitvision' ), -dh.nodes.header.h);

		if( this.currentLayer == 'cirkitvision' ){
			setTimeout( function(){ client.autosizeCirkitvision(); } , 200 );
		}
	},

	getCirkitvisionSize : function (){

		var height = dh.viewportH;
		var width = parseInt( (dh.viewportH / 1600 ) * 2705 );

		if( width < dh.viewportW ){
			width = dh.viewportW;
			height = parseInt( (dh.viewportW / 2705 ) * 1600 );
		}

		return [width,height];

	},

	getCirkitvisionSrc : function(){
		return "/api/servlets/ecImages?file=cirkitvision.jpg&fit=v&width=" + dh.viewportW + "&height=" + (dh.viewportH - dh.nodes.header.h);
	},

	openVideo : function ( videourl , index){
		if(!isEmpty(index)){
			var v = client.data.profileVideos[index];
			//console.log(v);
			if(v.videoStatus < 1 || !(v.embedSrc == '' && v.videoUrl == '')){
				if(profilePlayerSwf)profilePlayerSwf.style.left = "1000px";
				client.userError(	"CirkitVision",
									"We're sorry but CirkitVision does not current support this video format",
									function(){if(profilePlayerSwf)profilePlayerSwf.style.left = "0px";});
				return false;
			}
		}

		//open the cirkitvision tab
		this.initCirkitvision();
		this.ecvid = videourl;

	},

	getECVid: function(){
		return this.ecvid;
	}

};

function toEcirkit(){
	setTimeout( function () { client.openLayer( 'community' ); }, 100);
}

/******************************************************************
* 	Written By
*	Michael Grill - mike.RobotMojo.com
*	Eric Bittleman
*		2007
*
*	Documentation comming soon
*
*   NEW TODO - REMOVE THIS FILE

*	TODO 	events need a bind function that will determind to use addEventLister or .event
			mouse wheel data handling
* 			dragging / dropped property sets? predefined settings in objects (duh css)
* 			clone on drag   (vs.) moving on drag (moving includs detach child)
* 			dragChaining?  should a dropped item be cloned or dragged (extension of clone on drag)
* 			DONE* track Dragging/not dragging. (drag item, move mouse out of viewport let go, click on bg a dupe is created)
* 			might need to add setDragDrop function and setDraggable Function to prevent cross
* 							functionality interference (made that term up)
*
* 			tweening needs a sqrt map
			tween grouping - foreach(currentlytweeningobject in tweeningobjects)
*
* 			add draggedItemCount to end of dragging item ID - prevents dupes
* 			add dragTypes blah blah blah to dragdrop objects
* 			add multiple event handlers for dh objects
*
* 			check opacity tracking (load values on init)
* 			check event system, for completion
*
* 			getAbsX and getAbsY can be getAbsXY() then obj.absX , obj.absY; for speed
*
* 			dh.createDHObject or actually any DH functions should ONLY use DH objects! // need to check this
******************************************************************/
//---------------------------
// THE variable
//---------------------------
	var dh;
	var px = (!!(document.layers && typeof document.classes != dhNull)) ? '' : 'px'; //px suffix only for browsers that need it
	
//-----------------------
// Constants
//-----------------------

	//options used when adding an element to our structure
	var none = '';
	var staticElement = 	":a"; //cannot be re-initialized
	var forceOverwrite = 	":b"; //destroy old objects instead of exiting

	//dragdrop
	var dragdrop = 			":c";
	var dropzone = 			":d";
	var draggroup = 		":e";
	var maxCloneCount = 	":f"; //needs to be added
	var maxDropCount = 		":g";
	var cloneOnDrag = 		":h";
	var captureToParent = 	":i";
	//drag
	var draggable = 		":j";
	var vert =				":k";
	var horiz = 			":l";
	var sizeable = 			":m";
	var maxOffUp = 			":n";
	var maxOffDown = 		":o";
	var maxOffLeft = 		":p";
	var maxOffRight = 		":q";
	//graphical
	var alwaysOnTop = 		":r";
	var centerViewport = 	":s";
	var quickFade = 		":t";
	var fadeIn = 			":u";
	var fadeOut = 			":v";
	var visible = 			":x";
	var hidden = 			":y";
	var opacity = 			":z";
	var cursorHand = 		":A";

	//for testing undefined values
	var undefined;
	var dhNull;

	//for info dumping
	var DUMP_TEXT = false;
	var DUMP_HTML = true;

	//positionang options
	var POS_ABSOLUTE = 'a';
	var POS_RELATIVE = 'r';

	//HMTL Tags
	var HTML_ANCHOR = 	'a';
	var HTML_BODY = 	'body';
	var HTML_BUTTON = 	'button';
	var HTML_CHECKBOX = 'checkbox';
	var HTML_DIV = 		'div';
	var HTML_FORM = 	'form';
	var HTML_HIDDEN = 	'hidden';
	var HTML_IFRAME = 	'iframe';
	var HTML_IMAGE = 	'image';
	var HTML_INPUT = 	'input';
	var HTML_ORDEREDLIST = 'ol';
	var HTML_PARAGRAPH = 'p';
	var HTML_RADIO = 	'radio';
	var HTML_SPAN = 	'span';
	var HTML_TEXT = 	'text';
	var HTML_TEXTAREA = 'textarea';
	var HTML_UNORDEREDLIST = 'ul';

	var cursors = {
		normal : 	'normal',
		move : 		'move',
		moveEW : 	'normal',
		moveNS : 	'normal',
		pointer : 	'pointer'
	};
	//---------------------------
	// blank object
	//---------------------------
	function obj(){}

	function bind(obj, method) {
		return function(){ return method.apply(obj, arguments ); }
	}
	
	Function.prototype.bind = function(obj) {
		var method = this,
		temp = function() {
	   		return method.apply(obj, arguments);
		};
	 	return temp;
	}

	function indexOf(arr, needle, start) {
		if( arr.indexOf ) return arr.indexOf(arr, needle, start);
	    var start = start || 0;
	    for ( var i = start; i < arr.length; ++i ) {
	        if ( arr[i] === needle ) {
	            return i;
	        }
	    }
	    return -1;
	};

/* ***************************************************************
 * String Functions
 * ************************************************************* */
	/**  displays all properties and functions for an object
	 *
	 * @param {object}	obj		string to clean up
	 * @param {bool} 	html	newlines to be displayed as br or \n
	 * @param {int}		indent	level of indentation for recursion
	 *
	 * returns string
	 */
	function dumpObj( obj , html, indent){
		if(indent == dhNull) indent = 0;
		var thisLevel = ""; var indentText = "";
		for(var x = 0 ; x < indent ; x++) { indentText += "  "; }
		for(var a in obj) {
			var tmpO = obj[a];
			thisLevel += indentText + a + ": " + tmpO;
			thisLevel += (html) ? "<br />" : "\n";
		}
		return thisLevel;
	}

	//__________________________________________
	/** Removes leading and trailing whitespace
	 *
	 * @param {string} value		string to clean up
	 *
	 * returns string
	 */
	function trim(value) {
		if( !isString(value) ) return value; //we can only trim strings
		var temp = value;
		var obj = /^(\s*)([\W\w]*)(\b\s*$)/;
		if (obj.test(temp)) { temp = temp.replace(obj, '$2'); }
		var obj = / +/g;
		temp = temp.replace(obj, " ");
		if (temp == " ") { temp = ""; }
		return temp;
	}

	//__________________________________________
	/** Replaces all occcurences of a string in a string with a string
	 *
	 * @param {string} haystack		input string to search
	 * @param {string} needle		pattern to replace
	 * @param {string} replaceWith	new string to be inserted
	 *
	 * returns string
	 */
	function replaceAll (haystack, needle, replaceWith){
		var new_s = haystack;
		for (i = 0; i < 100 && new_s.indexOf (needle) != -1; i++)
			new_s = new_s.replace (needle, replaceWith);
		return new_s;
	}

	//__________________________________________
	/** Attempts to convert a css propert to a javascript fieldname
	 *
	 * @param {string} cssStr	a css property to guess as a DOM property
	 *
	 * returns string
	 */
	function toJavaStyle( cssStr ){
		var ary = cssStr.split('-');
		var quake = ary[0];
		var x = 0;
		for(x = 1 ; x < ary.length; x++){
			var chr = ary[x].charAt(0).toUpperCase();
			quake += chr + ary[x].substring(1);
		}
		return quake;
	}

/* ***************************************************************
 * Testing Functions
 * ************************************************************* */
	/** Tests a string for existence of a date
	 *
	 * @param {string} str		string to test for possible date
	 * returns bool
	 */
	function isDate(str){
		if(isEmpty(str)) return false;
		var dateFilter = /^(0[1-9]|1[012])[\/](0[1-9]|[12][0-9]|3[01])[\/](19|20)\d\d$/;
		return dateFilter.test(str);
	}

	//__________________________________________
	/** Tests a string for a vaild email address
	 *
	 * @param {string} str		a string containing an email address?
	 * returns bool
	 */
	function isEmail(str){
		if (isEmpty(str)) return false;
		var emailFilter  = /^\b[a-z0-9._%-]+@[a-z0-9.-]+\.[a-z]{2,4}\b$/;
		return emailFilter.test(str);
	}

	//__________________________________________
	/** Tests a string to a vaild URL
	 *
	 * @param {string} str		a string containing a URL?
	 * returns bool
	 */
	function isURL(str){
		if (isEmpty(str)) return false;
		var urlFilter = /^(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?$/;
		return urlFilter.test(str);
	}

	//__________________________________________
	/** A series of quick tests
	 * returns bool
	 */
	function inArray(hay, needle){ for(var a in hay) if(hay[a] == needle) return a; return false; }
	function isArray(obj){ return(typeof(obj.length) == "undefined")? false : true; }
	function isBoolean(a) {	return typeof a == 'boolean';}
	function isEmpty(str){ str = trim(str); return (str == null) || (str == 'null') || (str.length == 0) || (str == dhNull);}
	function isFunction(a) { return typeof a == 'function'; }
	function isNull(a) { return a === null; }
	function isNumber(a) { return typeof a == 'number' && isFinite(a); }
	function isObject(a) { return (a && typeof a == 'object') || isFunction(a); }
	function isString(a) { return typeof a == 'string'; }
	function isUndefined(a) { return typeof a == 'undefined'; }
	function ensureObject(obj){	return (isObject(obj)) ? obj : getObject(obj); }
	//prerequsiste of a nd b must be object refrences - there is no avoiding this prerequisite (error checking cannot be done as of now)
	function isAncestorOf(a , b){ var tmpObj = a; while(tmpObj){ if(tmpObj == b) return true; tmpObj = tmpObj.parentNode; } return false; }
	function getPageDomain () { return window.document.domain; }
	function getPageRootURL () { return "http://" + window.document.domain; }

/* ***************************************************************
 * DOM Functions
 * ************************************************************* */

	/*--------------------
	 * Create Object
	 * 	preconditions:
			tag is not null and a valid html tag
			id is  'none'  or string
			classname is  'none'  or string
			parent is parent element objref or  'none'
			innerHTML = any html to be inserted
			type = if input type is a form object, supply it's type
	 * usage: var newobj = createObject("div", "mnu1", "menuItem", menuDiv , "Help");
	 * or: var newobj = createObject("input", "id", "class", parent, "", "hidden");
	 */
	function createObject(tag, id, classname, parent, innerHTML, type){
		try{
			var tmpObject = document.createElement(tag);
			if (tag == "input" && type != dhNull) tmpObject.type = type;
			if(classname != dhNull) tmpObject.className = classname;
			if(id != dhNull){
				tmpObject.id = id;
				tmpObject.name = id;
			}
			parent = ensureObject(parent);
			if(parent != dhNull) parent.appendChild(tmpObject);

			if (tag == "input" && type != dhNull){
				tmpObject.value = innerHTML
			}else if(innerHTML != dhNull) {
				tmpObject.innerHTML = innerHTML;
			}
		}
		catch(e) { /*alert("createObject Error");*/ }
		return tmpObject;
	}

	/**	removes an element from the DOM - warning
	 * 
	 * could be buggy - needs to check for scripted objectids and dhnodes. damn dhnodes.
	 * 
	 * deleteObject
	 * @param {element} objectID	DOM id of object to be deleted from the dom
	 *
	 * returns true on success / false on error
	 */
	function deleteObject(objectID){
		var obj = getObject(objectID);
		try{ obj.parentNode.removeChild(obj);
		} catch(e) { return false; }
		return true;
	}


	/**	returns a DOM element based on an ID
	 *
	 * getObject
	 * @param {element} objectID	DOM id of object to be found
	 *
	 * if an object refence is passed, it will be returned back immediately
	 *
	 * returns HTMLElement
	 */
	function getObject(objectID){
		if(isObject(objectID)) return objectID; //in the event the object was passed
		try	{
		  if (document.getElementById) { return document.getElementById(objectID); }
		  else if (document.all) { return document.all[objectID]; }
		  else if (document.layers) { return document.layers[objectID]; }
		} catch(e) { alert("Error: "+objectID+"\n"+e); }
	}

	/** gets all elements in the DOM by their className
	 *
	 * getElementsByClassName
	 * @param {string} oElm				root element
	 * @param {string} strTagName		* or a tag name to search specifically
	 * @param {string} strClassName		classname to look for
	 *
	 * eg. getElementsByClassName(document, "a", "info-links");
	 *
	 * returns array
	 */
	function getElementsByClassName(oElm, strTagName, strClassName){
	    var arrElements = (strTagName == "*" && oElm.all) ? oElm.all : oElm.getElementsByTagName(strTagName);
	    var arrReturnElements = new Array();
	    strClassName = strClassName.replace(/\-/g, "\\-");
	    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
	    var oElement;
	    for(var i=0; i<arrElements.length; i++){
	        oElement = arrElements[i];
	        if(oRegExp.test(oElement.className)){
	            arrReturnElements.push(oElement);
	        }
	    }
	    return (arrReturnElements)
	}

	/** gets an array of all flash objects in the dom
	 * getFlashObjects
	 * returns array
	 */
	function getFlashObjects(){
		var arrObj = document.getElementsByTagName("object");
		var arrEmb = document.getElementsByTagName("embed");

		if( !isArray(arrObj) || !isArray(arrEmb) ) return false;

		var allObj = [];
		
		if( arrObj.length > 0 && arrEmb.length > 0 ){
			for( var a = 0 ; a < arrObj.length; a++ ) allObj[ allObj.length ] = arrObj[a];
			for( var b = 0 ; b < arrEmb.length; b++ ) allObj[ allObj.length ] = arrEmb[b];
		} else if( arrObj.length > 0 ){
			allObj = arrObj;
		} else if( arrEmb.length > 0 ){
			allObj = arrEmb;
		}

		return ( allObj.length > 0 ) ? allObj : false ;
	}


	/** set all visible flash objects to invisible
	 *
	 * hideFlashObjects
	 *
	 * returns nothing
	 */	
	function hideFlashObjects(){
		var flashObjects = getFlashObjects();
		if( flashObjects ) for (i = 0; i < flashObjects.length; i++) invisible( flashObjects[i] ); 
	}

	/** set visibility to al hidden flash objects
	 *
	 * showFlashObjects
	 *
	 * returns nothing
	 */	
	function showFlashObjects(){
		var flashObjects = getFlashObjects();
		if( flashObjects ) for (i = 0; i < flashObjects.length; i++) reappear( flashObjects[i] ); 
	}


	/** sets an elements parent
	 *
	 * setParent
	 * @param {object} obj						element to move
	 * @param {string | object } newParent		ID or object reference of new parent element
	 *
	 * returns true on success / false on error
	 */
	function setParent(obj, newParentID){
		try{ var elementRef = obj.parentNode.removeChild(obj);
			 var t = getObject(newParentID);
			 var o = t.appendChild(elementRef);
		} catch (e){ return false; }return true;
	}
	
	/**
	 *
	 * insertBefore
	 * @param {object} obj						element to move
	 * @param {string | object } newNeighbor	ID or object reference of new adjacent element
	 *
	 * returns true on success / false on error
	 */
	function insertBefore(obj, newNeighbor){
		try{ obj.parentNode.removeChild(obj);
			 var t = getObject(newNeighbor);
			 var o = newNeighbor.parentNode.insertBefore(obj, newNeighbor);
		} catch (e){ return false; }return true;
	}
	
	/**
	 *
	 * setStyle
	 * @param {object} obj						element to style
	 * @param {string | object } name	ID or object reference of new adjacent element
	 * @param {string | object } value
	 *
	 * returns true on success / false on error
	 */	
	function setStyle(element, name, value) {
		eval('element.style.' + name + ' = value;');
	}
/* ***************************************************************
 * DHTML Functions
 * ************************************************************* */
	//-----------------------------------------------
	// Info functions
	//-----------------------------------------------

	/**	
	 * Core code from - quirksmode.com
	 * getPageScroll()
	 * returns array with x,y page scroll values.
	 */	
	function getPageScroll(){
	
		var xScroll, yScroll;
	
		if (self.pageYOffset) {
			yScroll = self.pageYOffset;
			xScroll = self.pageXOffset;
		} else if (document.documentElement && document.documentElement.scrollTop){	 // Explorer 6 Strict
			yScroll = document.documentElement.scrollTop;
			xScroll = document.documentElement.scrollLeft;
		} else if (document.body) {// all other Explorers
			yScroll = document.body.scrollTop;
			xScroll = document.body.scrollLeft;	
		}
	
		arrayPageScroll = new Array(xScroll, yScroll) 
		return arrayPageScroll;
	}
	
	/**	
	 * Core code from - quirksmode.com
	 * Edit for Firefox by pHaez
	 * 
	 * getPageSize()
	 * returns array with page width, height and window width, height
	 */	
	function getPageSize(){
		
		var xScroll, yScroll;

		var docBody = (document.compatMode && document.compatMode.toLowerCase() != "backcompat")?
			document.documentElement : (document.body || null);
		
		if (window.innerHeight && window.scrollMaxY) {	
			xScroll = window.innerWidth + window.scrollMaxX;
			yScroll = window.innerHeight + window.scrollMaxY;
		} else if (docBody.scrollHeight > docBody.offsetHeight){ // all but Explorer Mac
			xScroll = docBody.scrollWidth;
			yScroll = docBody.scrollHeight;
		} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}
		
		var windowWidth, windowHeight;

		if (self.innerHeight) {	// all except Explorer
			if(document.documentElement.clientWidth){
				windowWidth = document.documentElement.clientWidth; 
			} else {
				windowWidth = self.innerWidth;
			}
			windowHeight = self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
			windowWidth = document.documentElement.clientWidth;
			windowHeight = document.documentElement.clientHeight;
		} else if (document.body) { // other Explorers
			windowWidth = document.body.clientWidth;
			windowHeight = document.body.clientHeight;
		}	
		
		// for small pages with total height less then height of the viewport
		if(yScroll < windowHeight){
			pageHeight = windowHeight;
		} else { 
			pageHeight = yScroll;
		}

		// for small pages with total width less then width of the viewport
		if(xScroll < windowWidth){	
			pageWidth = xScroll;		
		} else {
			pageWidth = windowWidth;
		}

		arrayPageSize = new Array(pageWidth, pageHeight, windowWidth, windowHeight) 
		return arrayPageSize;
	}
	
	//these scroll bar function only acocunt for vertical scrolling
	//due to the nature of a scrollwheel.
	function hasScrollBar( element ){		return (element.scrollHeight != element.offsetHeight);	}
	function canScrollDown( element ){		return ( element.scrollTop != (element.scrollHeight - element.offsetHeight));	}
	function canScrollUp( element ){		return ( element.scrollTop != 0 );	}
	function enableScrolling ( element ){	element.className = element.className.replace(/(\\noscroll)|(noscroll)/, '');	}
	function disableScrolling ( element ){ 	element.className += ' noscroll'; }
	
	//-----------------------------------------------
	// Graphical Functions
	//-----------------------------------------------
	/** Visually and computationally hides an element
	 *
	 * hideObject
	 * @param {object} obj		element to hide
	 * returns true on success / false on error
	 */
	function hideObject(obj) {
		try {
			if(!isObject(obj) ) return false;
			obj.style.visibility = 'hidden';
			obj.style.display = 'none';
		} catch (e) { return false; }
		return true;
	}

	/** Visually and computationally shows an element
	 *
	 * showObject
	 * @param {object} obj		element to show
	 * returns true on success / false on error
	 */
	function showObject(obj) {
		try{
			if(!isObject(obj) ) return false;
			obj.style.visibility = 'visible';
			obj.style.display = 'block';
		} catch (e) { return false; }
		return true;
	}

	/** computationally hides an element
	 *
	 * hideBlock
	 * @param {object} obj		element to hide
	 * returns true on success / false on error
	 */
	function hideBlock( element ){
		return setStyle( element, 'display', 'none');
	}

	/** computationally shows an element
	 *
	 * showBlock
	 * @param {object} obj		element to show
	 * returns true on success / false on error
	 */
	function showBlock( element ){
		return setStyle(element, 'display', 'block');
	}

	/** visually hides an element
	 *
	 * invisible
	 * @param {object} obj		element to show
	 * returns true on success / false on error
	 */
	function invisible( element ){
		return setStyle(element, 'visibility', 'hidden');
	}

	/** visually shows an element
	 *
	 * visible
	 * @param {object} obj		element to show
	 * returns true on success / false on error
	 */
	function reappear( element ) {
		return setStyle(element, 'visibility', 'visible');
	}

	/** sets the Background color of an element
	 *
	 * setBgColor
	 * @param {HTMLElement} obj		element to show
	 * returns true on success / false on error
	 */
	function setBgColor( element , color){
		try{ element.style.backgroundColor = color; }
		catch (e) { return false; } return true;
	}

	/** sets the Background color of an element
	 *
	 * setBgColor
	 * @param {HTMLElement} obj		element to show
	 * returns true on success / false on error
	 */
	function setBgImage( element, url, options){
		try{ 
			if( options != dhNull ) {
				element.style.background = "url(" + url + ") " + options;
			} else {
				element.style.backgroundImage = "url(" + url + ")";
			}
		}
		catch (e) { return false; } return true;
	}

	/** sets all background properties
	 *
	 * setBackground
	 * @param {string} url		path to an image
	 * returns true on success / false on error
	 */
	function setBackground(element, color, url, posx, posy, repeat ){
		var bgStyle = "";

		//set any colors
		if (color){ 
			//make sure the color has a #
			if( color.indexOf("#") < 0 ) color = "#" + color;
			bgStyle += color + " ";
		}

		//if a bg is found.
		if( url ){
			//add the url tags 
			bgStyle += "url(" + url + ") ";
		}
		
		if( posx ) bgStyle += posx + " ";
		if( posy ) bgStyle += posy + " ";
		
		//set repeat values
		if( repeat ) bgStyle += repeat + " ";
		
		element = getObject(element);
		if(element)element.style.background = bgStyle;
	}

	/** resets all background properties
	 *
	 * resetBackground
	 * @param {string} url		path to an image
	 * returns true on success / false on error
	 */
	function resetBackground(element){
		var bgStyle = "";
		element = getObject(element);
		if(element)element.style.background = bgStyle;
	}
	
	
	function setOpacity(element , opacity){
		try{
			if(typeof element.style.MozOpacity != undefined){	element.style.MozOpacity = opacity / 100; }
			if(typeof element.style.filter != undefined){	element.style.filter = "Alpha(opacity="+parseInt(opacity)+")";	}
			element.style.opacity = opacity / 100;
		} catch (e) { return false; } return true;
	}


	//-----------------------------------------------
	// Positioning Functions
	//-----------------------------------------------
	function X(element, value){
		try{
			if(value != dhNull && value != "NaN") {
				element.style.left = parseInt(value) + dh.px;
			} else if( value == dhNull ){
				return getX(element);
			}
		} catch (e){
			return 0;
		}
		return parseInt(value);
	}
	
	function Y(element, value){
		try{
			if(value != dhNull && value != "NaN") {
				element.style.top = parseInt(value) + dh.px;
			} else if( value == dhNull ){
				return getY(element);
			}
		} catch (e){
			return 0;
		}
		return parseInt(value);
	}
	
	/**	gets the X position of any element to it's offsetParent
	 * getX
	 * @param {element} element		dom element to calculate for.
	 * returns number
	 */
	function getX( element ){
		var curleft = 0;
		var tmpobj = element;
		if (tmpobj.offsetParent) { curleft += tmpobj.offsetLeft; }
		else if (tmpobj.x) curleft += tmpobj.x;
		return curleft;
	}

	/**	gets the Y position of any element to it's offsetParent
	 * getY
	 * @param {element} element		dom element to calculate for.
	 * returns number
	 */
	function getY(element){
		var curtop = 0;
		var tmpobj = element;
		if (tmpobj.offsetParent) { curtop += tmpobj.offsetTop; }
		else if (tmpobj.y)	curtop += tmpobj.y;
		return curtop;
	}

	/**	gets the absolute X position of any element to the origin
	 * getAbsX
	 * @param {element} element		dom element to calculate for.
	 * returns number
	 */
	function getAbsX( element ){
		var curleft = 0;
		var tmpobj = element;
		if (tmpobj.offsetParent) {
			while (tmpobj.offsetParent) {
					curleft += tmpobj.offsetLeft;
					if( tmpobj.tagName.toLowerCase() == 'div' ){ curleft -= tmpobj.scrollLeft; }
					tmpobj = tmpobj.offsetParent;
				}
		}
		else if (tmpobj.x) { curleft += tmpobj.x; }
		return curleft;
	}

	/**	gets the absolute Y position of any element to the origin
	 * getAbsX
	 * @param {element} element		dom element to calculate for.
	 * returns number
	 */
	function getAbsY(element){
		var curtop = 0;
		var tmpobj = element;
		if (tmpobj.offsetParent) {
			while (tmpobj.offsetParent) {
				curtop += tmpobj.offsetTop
				if( tmpobj.tagName.toLowerCase() == 'div' ){ curtop -= tmpobj.scrollTop; }
				tmpobj = tmpobj.offsetParent;
			}
		}
		else if (tmpobj.y) { curtop += tmpobj.y; }
		return curtop;
	}

	/**	gets the absolute X position of any element to the origin
	 * getAbsX
	 * @param {element} element		dom element to calculate for.
	 * returns number
	 */
	function getRelativeAbsX( elementA, elementB ){
		var curleft = 0;
		var tmpobj = elementA;
		if (tmpobj.offsetParent) {
			while (tmpobj.offsetParent && tmpobj != elementB) {
					curleft += tmpobj.offsetLeft;
					if( tmpobj.tagName.toLowerCase() == 'div' ){ curleft -= tmpobj.scrollLeft; }
					tmpobj = tmpobj.offsetParent;
				}
		}
		else if (tmpobj.x) { curleft += tmpobj.x; }
		return curleft;
	}

	/**	gets the absolute Y position of any element to the origin
	 * getAbsX
	 * @param {element} element		dom element to calculate for.
	 * returns number
	 */
	function getRelativeAbsY(elementA, elementB){
		var curtop = 0;
		var tmpobj = elementA;
		if (tmpobj.offsetParent) {
			while (tmpobj.offsetParent && tmpobj != elementB) {
				curtop += tmpobj.offsetTop
				if( tmpobj.tagName.toLowerCase() == 'div' ){ curtop -= tmpobj.scrollTop; }
				tmpobj = tmpobj.offsetParent;
			}
		}
		else if (tmpobj.y) { curtop += tmpobj.y; }
		return curtop;
	}

	//-----------------------------------------------
	// Sizing Functions
	//-----------------------------------------------
	/**	gets the visible width of an element
	 * getvW
	 * @param {element} element		dom element to calculate for
	 * returns number
	 */
	function getW( element ) {
		try{
		return (dh.ns4) ?
			(element) ?	element.clip.width : 0
			: (element) ? (element.offsetWidth || element.style.pixelWidth || element.style.width || 0) : 0;
		} catch (e){ } return false;
	}


	/**	gets the visible height of an element
	 * getH
	 * @param {element} element		dom element to calculate for.
	 * returns number
	 */
	function getH( element ) {
		try{
		return (dh.n4) ?
			(element) ? element.clip.height : 0
			: (element) ? (element.offsetHeight || element.style.pixelHeight || element.style.height || 0) : 0;
		} catch (e) {} return false;
	}

	/**	gets the client(inner) width of an element ( scrollbars not included )
	 * getvW
	 * @param {element} element		dom element to calculate for
	 * returns number
	 */
	function getInnerW( element ) {
		try{
		return (element.clientWidth || 0);
		} catch (e) {} return false;
	}


	/**	gets the client(inner) height of an element ( scrollbars not included )
	 * getH
	 * @param {element} element		dom element to calculate for.
	 * returns number
	 */
	function getInnerH( element ) {
		try{
		return (element.clientHeight || 0);
		} catch (e) {} return false;
	}

	function W (element, value) {
		try {
			if(value != dhNull && parseInt(value) != "NaN") {
				value = (value < 0)? 0 : value;
				element.style.width = parseInt(value) + px;
			}
		}catch(e){ return false; }
		return true;
	}
	function H (element, value) {
		try{
			if(value != dhNull && parseInt(value) != "NaN") {
				value = (value < 0) ? 0 : value;
				element.style.height = parseInt(value) + px;
			}
		} catch (e){ return false; }
		return true;
	}
	
/* ***************************************************************
 * Form / Input Field  Functions
 * ************************************************************* */
	/**	gets the absolute Y position of any element to the origin
	 * setValue
	 * @param {element} element		dom element to calculate for.
	 * returns number
	 */
	function setValue( element, value){
		value = trim(value);
		if (element.type != dhNull){
			if(element.type.toLowerCase() == HTML_RADIO) return radioValue(element.id,value);
		}
		element.value = trim(value);
		return element.value;
	}

	/**	gets the absolute Y position of any element to the origin
	 * getValue
	 * @param {element} element		dom element to calculate for.
	 * returns number
	 */
	function getValue( element ){
		if(element.type != dhNull){
			if(element.type.toLowerCase() == HTML_RADIO) return radioValue(element.id);
		}
		return element.value;
	}

	/**	gets the absolute Y position of any element to the origin
	 * isChecked
	 * @param {element} element		dom element to calculate for.
	 * returns number
	 */
	function isChecked(element, check){ //will set checked if given and always returns the value
		if(check != dhNull) element.checked = check;
		return element.checked;
	}

	/**	gets the absolute Y position of any element to the origin
	 * radioValue
	 * @param {element} element		dom element to calculate for.
	 * returns number
	 */
	function radioValue(radioID, ch){ //will set checked if given and always returns the value
		var value = false;
		var radios = document.getElementsByName(radioID);
		for(var i = 0; i < radios.length; i++){
			if(ch != dhNull){ //setting and getting
				radios[i].checked = (ch == radios[i].value) ? true : false;
			} else{ //just checking for getValue
				if(radios[i].checked) return radios[i].value;
			}
		}
		return ch;
	}


//************************************
// Core DHTML Object
//************************************
function dhInit(){
	dh = new DHTML(); //create our object
	// Register Mouse Events on document/window
	//window.onclick = document.onclick = __click;
	document.onmousemove = dh.__mousemove;
	document.onmouseup = dh.__mouseup;
	document.onmousedown = dh.__mousedown;
	window.onscroll = dh.__scroll;
	window.onresize = dh.__resize;
	dh.event_resize();
	dh.event_scroll();
	
	/*mouse wheel*/
	//if (window.addEventListener) window.addEventListener('DOMMouseScroll',  dh.__mousewheel, false);
	//else window.onmousewheel = document.onmousewheel = dh.__mousewheel;
}

function DHTML(){
	//-------------------
	// Object definitions
	//-------------------
	this.nodes = new Array(); //DOM elements object
	this.empty = function(){}; //for recreating the object later on

	//some browser detection
	//this code was orignally from walter zorn - wz_dragdrop.js - a well written drag & drop library
	//          www.walterzorn.com
	//some minor changes were made because of IE7 added an ie6
	//removed ce, depreciated
	this.n = navigator.userAgent.toLowerCase();
	this.docBody = (document.compatMode && document.compatMode.toLowerCase() != "backcompat")?
		document.documentElement : (document.body || null);
	this.safari = (this.n.indexOf("safari") != -1) ? true : false;
	this.ie = !!(this.n.indexOf("msie") >= 0 && document.all && this.docBody);
	this.iemac = !!(this.ie && this.n.indexOf("mac") >= 0);
	this.ie4 = !!(this.ie && !document.getElementById);
	this.ie6 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 6.")!=-1)) ? true : false;
	this.ie7 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 7.")!=-1)) ? true : false;
	this.ff = (this.n.indexOf("firefox") != -1 ) ? true : false;
	this.n4 = !!(document.layers && typeof document.classes != dhNull);
	this.n6 = !!(typeof window.getComputedStyle != dhNull && typeof document.createRange != dhNull);
	this.px = this.n4 ? '' : 'px';
}

function tween(obj, tweenInfo, whenDone){
	var step = tweenInfo.steps.pop();
	if( !step ){
		if( tweenInfo.x ) obj.X( tweenInfo.x );
		if( tweenInfo.y ) obj.Y( tweenInfo.y );
		if( tweenInfo.w ) obj.W( tweenInfo.w );
		if( tweenInfo.h ) obj.H( tweenInfo.h );
		if( tweenInfo.alpha ) obj.setOpacity( tweenInfo.alpha );
		//the functions we're using to move and resize do not call these event handlers
		//they were used for the purpose of speed, so the event handler for resizing
		//would not be called for each frame of the tween
		obj.invoke("Resize");
		obj.invoke("Move");
		dh.tweening = false;
		if( whenDone ) whenDone(obj, tweenInfo );
		return;
	}
	if( step.x ) obj.X( step.x );
	if( step.y ) obj.Y( step.y );
	if( step.w ) obj.W( step.w );
	if( step.h ) obj.H( step.h );
	if( step.opacity ) obj.setOpacity( step.opacity );
	setTimeout(
		function() { tween(obj, tweenInfo, whenDone); },
		parseInt( tweenInfo.duration / tweenInfo.incrementCount )
	);
}

function quickTween( htmlElement, destinationValues, frameDelay, frameCount, whenDone){
	setTimeout( buildQuickTween(htmlElement, destinationValues, frameDelay, frameCount, 1, whenDone), 0 );
}

function buildQuickTween( htmlElement, differences, frameDelay, frameCount, currentFrame, whenDone ){
	return (currentFrame < frameCount) ? 
		function (){ 

			if(differences.diffX) 		X(htmlElement, differences.destX - (differences.diffX / currentFrame) );
			if(differences.diffY) 		Y(htmlElement, differences.destY - (differences.diffY / currentFrame) );
			if(differences.diffW) 		W(htmlElement, differences.destW - (differences.diffW / currentFrame) );
			if(differences.diffH) 		H(htmlElement, differences.destH - (differences.diffH / currentFrame) );
			if(differences.diffAlpha) 	setOpacity(htmlElement, differences.destAlpha + (differences.diffAlpha / currentFrame));

			var next = buildQuickTween( htmlElement, differences, frameDelay, frameCount, currentFrame + 1, whenDone );
			if(next) setTimeout(next, frameDelay);
		} 
		:
		whenDone;
}

DHTML.prototype = {
	//---------------------
	// Object properties
	//---------------------
		dragObject : dhNull, //current object with focus
		tmpDragObject : "tdoxegg", //random text for temp drag ObjectID - prevents ocnflicts with object ID's
		tweening : false,
		dropZones : [],

		//__________________
		// Movement tracking
		//------------------
			mouseX : 0,
			mouseY : 0,

			mouseStartX : 0,
			mouseStartY : 0,
			objStartX : 0,
			objStartY : 0,

			offsetx : 0,	// position of mouse cursor on object
			offsety : 0,
			absX : 0,		//page based offset of object before drag
			absY : 0,		//needed for relative position calculation

		//____________________
		// General monitoring
		//--------------------
			scrollLeft : 0,
			scrollTop : 0,
			highz : 3000,		//highest current z index , start it at something good so we don't gou under any existing elements

			viewportW : 0,
			viewportH : 0,
			documentW : 0,
			documentH : 0,

		//______________
		// Events
		//--------------
			eventTarget : dhNull,
			eventTargetID:	'',
			eventTargetElement: dhNull,
			resizeEvents : {},
			scrollEvents : {},
			mouseDownEvents : Array(),
			mouseMoveEvents : Array(),
			mouseUpEvents : Array(),
			mouseWheel : Array(),
			//some custom Drag Drop events
			onGrab : dhNull,
			onDrag : dhNull,
			onDrop : dhNull,


	//-----------------------
	// Debug
	//-----------------------
	dump : function (html) { //set html to true when writing to a div / html element
		var newline;
		html == true ? newline = "<br>\n" : newline = "\n";
		output = "drag object name: " + this.dragObject.name +  newline;
		output += "absX: " + this.absX +  newline;
		output += "absY: " + this.absY + newline;
		output += "offsetX: " + this.offsetX +  newline;
		output += "offsetY: " + this.offsetY + newline;
		output += "highz: " + this.highz + newline;
		return output;
	},

	//-----------------------
	// Find HTML Objects
	//-----------------------
	getObject : function (objectid){
		return getObject(objectid);
	},

	//**************************
	// Create Objects
	//**************************
	createDHObject : function(tag, id, classname, parent, innerHTML, dhFlags){
		if(id == dhNull){
			alert("Cannot create dhObj without element ID");
			return;
		}
		var obj = createObject(tag, id, classname, parent, innerHTML);
		dh.addObject(id, dhFlags);
		return dh.nodes[id];
	},

	//**************************
	// Tween Info Object
	//**************************
	tweenDetails : function(x, y, w, h, alpha, duration, incrementCount){
		return { x:x,y:y,w:w,h:h,alpha:alpha,duration:duration,incrementCount:incrementCount,currentIncrement:0};
	},

	//**************************
	// Return a settings value
	//**************************
	getSetting: function ( needle, settings ){
		if( settings.indexOf(needle) > -1) return true;
		return false;
	},

	//**************************
	// Attach Object
	//**************************
	addObject : function(objectid, settings) {
		//ensure we don't add the same one twice
		//if( this.nodes[objectid] == dhNull ) return false;
		var settings = settings + ":"; //error correction for parsing values with options.

		if( this.getSetting(forceOverwrite , settings) ){
			try{
				var dhobj = this.nodes[objectid];
				dhobj.destroy();
			} catch(e) {
				//couldn't destroy old element
			}
		}

		var dhobj = new DHNode(objectid);
		this.nodes[objectid] = dhobj;

		if(this.highz < dhobj.z) this.highz = dhobj.z; 		//check our high z index

		if( this.getSetting(staticElement , settings) ){
			dhobj.allowInitialize = false;
		}

		if( this.getSetting(centerViewport , settings) ){
			dhobj.centerOnShow = true;
		}
		if( this.getSetting(alwaysOnTop , settings) ){
			dhobj.alwaysOnTop = true;
		}

		//---------
		// DragDrop
		//---------
		if( this.getSetting(dragdrop , settings) ){
			dhobj.dragDrop = true;
		}
		if( this.getSetting(draggable , settings) ){
			dhobj.draggable = true;
		}
		if( this.getSetting(dropzone , settings) ){
			dhobj.dropZone = true;
			this.dropZones[this.dropZones.length] = dhobj;
		}
		op = settings.indexOf(draggroup);
		if(op != -1){
			ad = settings.indexOf(":", op + 1);  //ammount delimiter
			op += 2; // move the beginning to after the option string
			dhobj.dragGroup = settings.substring(op, ad);
		}
				

		op = settings.indexOf(maxCloneCount);
		if(op != -1){
			ad = settings.indexOf(":", op + 1);  //ammount delimiter
			op += 2; // move the beginning to after the option string
			dhobj.maxCloneCount = settings.substring(op, ad);
		}
		op = settings.indexOf(maxDropCount);
		if(op != -1){
			ad = settings.indexOf(":", op + 1);  //ammount delimiter
			op += 2; // move the beginning to after the option string
			dhobj.maxDropCount = settings.substring(op, ad);
		}
		if( this.getSetting(cloneOnDrag , settings) ){
			dhobj.cloneOnDrag = true;
		}

		if( this.getSetting(captureToParent , settings) ){
			dhobj.captureToParent = true;
		}

		//---------
		// Graphical
		//---------
		op = settings.indexOf(opacity);
		if(op > -1){
			ad = settings.indexOf(":", op + 1);  //ammount delimiter
			op += 2; // move the beginning to after the option string
			dhobj.setOpacity(settings.substring(op, ad));
		}
		if( this.getSetting(visible , settings) 	){ dhobj.show(); }
		if( this.getSetting(hidden , settings) 		){ dhobj.hide(); }
		if( this.getSetting(fadeIn , settings) 		){ dhobj.fadeIn = true; }
		if( this.getSetting(fadeOut , settings) 	){ dhobj.fadeOut = true; }
		if( this.getSetting(cursorHand , settings) 	){ dhobj.style.cursor = 'pointer'; }

		//---------
		// Drag
		//---------
		if( this.getSetting(vert , settings) 	) dhobj.vertical = true;
		if( this.getSetting(horiz , settings) 	) dhobj.horiz = true;
		if( this.getSetting(sizeable , settings)) { } //TODO

		mo = settings.indexOf(maxOffUp);
		if(mo > -1){
			ad = settings.indexOf(":", mo + 1);  //ammount delimiter
			mo += 2; // move the beginning to after the option string
			dhobj.maxOffsetUp = settings.substring(mo, ad);
		}
		mo = settings.indexOf(maxOffDown);
		if(mo > -1){
			ad = settings.indexOf(":", mo + 1);  //ammount delimiter
			mo += 2; // move the beginning to after the option string
			dhobj.maxOffsetDown = settings.substring(mo, ad);
		}
		mo = settings.indexOf(maxOffLeft);
		if(mo > -1){
			ad = settings.indexOf(":", mo + 1);  //ammount delimiter
			mo += 2; // move the beginning to after the option string
			dhobj.maxOffsetLeft = settings.substring(mo, ad);
		}
		mo = settings.indexOf(maxOffRight);
		if(mo > -1){
			ad = settings.indexOf(":", mo + 1);  //ammount delimiter
			mo += 2; // move the beginning to after the option string
			dhobj.maxOffsetRight = settings.substring(mo, ad);
		}

		//******************************
		//Incoming events
		// only those that cannot be
		// handled by the window event mapping
		//******************************/
		dhobj.bindDOMEvents();

		return dhobj;
	},

	initAll : function(resetDefaults){
		if(resetDefaults == dhNull) resetDefaults = null;
		for(var key in this.nodes){
			var tmpObj = this.nodes[key];
			if(!tmpObj.visible){
				tmpObj.showBlock();
				tmpObj.initialize(resetDefaults);
				tmpObj.hideBlock();
			} else {
				tmpObj.initialize(resetDefaults);
			}
		}
	},


	//**************************
	// shorthand object refrence
	//**************************
	$: function(objectid) {
		try{ return this.nodes[objectid]; }
		catch(e){} return false;
	},

	//**************************
	// Detach Object
	//**************************
	detachNode: function(objectid) {

		//TODO add event for destroy
		if( dh.nodes[objectid].cloneParent ){
			var cloneParent = dh.nodes[objectid].cloneParent;
			cloneParent.clones.splice( 
				indexOf( cloneParent.droppedItems, this),
				1 
			);
		}
		
		if( dh.nodes[objectid].dropParent ){
			var dropParent = dh.nodes[objectid].dropParent;
			dropParent.droppedItems.splice(
				indexOf( dropParent.droppedItems, this),
				1
			);
		}

		delete this.nodes[ objectid ];
		//delete it from the elements list
		//this.nodes.splice( objectid , 1 );
	},

	//**************************
	// Sizing Functions
	//**************************
	getWndW : function(){ return this.docBody.clientWidth; },
	getWndH : function(){ return this.docBody.clientHeight; },

	//**************************
	// Events
	//**************************
		//incomming event handlers
		__mousemove:function(e){ if( dh.tweening ) return; dh.getEventObject(e); return dh.event_mouseMove(); },
		__mouseup:	function(e){ dh.getEventObject(e); return dh.event_mouseUp(); },
		__mousedown:function(e){ dh.getEventObject(e); return dh.event_mouseDownEvents(); },
		__mousewheel:function(e){ dh.getEventObject(e); return dh.event_mouseWheel(); },
		__scroll:	function(e){ dh.getEventObject(e); return dh.event_scroll(); },
		__resize:	function(e){ dh.getEventObject(e); return dh.event_resize(); },

	getEventObject : function(e) {
		try{
			if (!e) var e = window.event;
			this.event = e; //save for other uses
			this.eventTargetElement = e.srcElement || e.target;
			this.eventTargetID = this.eventTargetElement.id || this.eventTargetElement.name;
			if(objid == '' || objid == dhNull){
				this.eventTarget = dhNull;
				return;
			}
		}
		catch(E){ this.eventTarget = dhNull; }
		try{
			this.eventTarget = eval('this.nodes.' + objid);
			this.event.targetID = objid;
		}
		catch(E){ this.eventTarget = dhNull; }
	},

	stopEvent : function(e){
		var thisEvent = (!e) ? window.event : e;

		try{ thisEvent.cancelBubble = true;	}catch(ex){ }
		try{ thisEvent.stopPropagation();	}catch(ex){ }
		try{ thisEvent.preventDefault();	}catch(ex){ }
		try{ thisEvent.returnValue = false;	}catch(ex){ }

	},

	invoke : function(ev){
		try { return this['on' + ev](); }
		catch (ex){ } return true;
	},
	//---------------------------------------------------
	//- Sizing Events
	//---------------------------------------------------
	event_resize : function (e){

	 	var pageSizes = getPageSize();
		
		this.documentW = pageSizes[0];
		this.documentH = pageSizes[1];
		
		this.viewportW = pageSizes[2];
		this.viewportH = pageSizes[3];

		//call our callbacks
		for(var evKey in this.resizeEvents)	{
			var callback = this.resizeEvents[evKey];
			callback(e);
		}
	},

	addResizeEvent : function (eventKey, action){
		this.resizeEvents[eventKey] = action;
	},

	removeResizeEvent : function (eventKey){
		delete this.resizeEvents[eventKey];
	},

	//---------------------------------------------------
	//- Mouse Events
	//---------------------------------------------------
	//bring an HTML elemtns to frint and still retain integrity in dh.currentZindex
	bringToFront : function (HTMLElement, forceOnTop){
			dh.highz++;
			if( forceOnTop ){
				setZ(HTMLElement,  dh.highz + 7000 ); //always on top is sudo 10000
			} else {
				setZ(HTMLElement,  dh.highz );
			}
	},
	
	//*******
	// for multiple mouse down handlers
	//********
	addMouseDownEvent : function (eventKey, action){ this.mouseDownEvents[eventKey] = action; },
	removeMouseDownEvent : function (eventKey){ delete this.mouseDownEvents[eventKey]; },	
	event_mouseDownEvents : function (e) {
		//call our callbacks
		for(var evKey in this.mouseDownEvents)	{
			var callback = this.mouseDownEvents[evKey];
			callback(e);
		}

		return true; //return false for dragging, so events don't go too far
	},
	
	//*******	
	//A Per Element assigned mouse down halder for drag drop.
	//*******
	event_mouseDown : function (e) {
		
		//any element can only be 'grabbed' if it can be dragged
		if(this.dragObject.draggable || this.dragObject.dragDrop){
			//call the objects on grab event
			this.dragObject.event_onGrab(e)
			
			//global grab	
			this.invoke("Grab");
		}
//		if( !this.dragObject.event_onGrab(e) ){
//			console.log( this.dragObject );
//			return false;
//		}

		if(this.event.target){
			if (this.event.target.nodeName == "TEXTAREA" ||	this.event.target.nodeName == "INPUT"){
				this.dragObject = null;
				return;
			}
		}

		//this is a drag & drop source element, make a clone, 50% opacity and make it the drag object
		if(this.dragObject.dragDrop){
			
			//this is a drag and drop object, but theres no drop zones...
			//no need to waste time form here. just exit.
			if ( !dh.dropZones ){ return; }
			
			//ok so there's oging to be someplace to drag to,
			//cancel the browser's default actions
			dh.stopEvent(e); 

			//get our dragStart so we can animate back if need be.
			var dsx = this.dragObject.getAbsX();
			var dsy = this.dragObject.getAbsY();
			
			if(this.dragObject.cloneOnDrag == true){ 
				//we're goanna clone it
				var newCloneIndex = (this.dragObject.clones) ? this.dragObject.clones.length : 0;
				
				//is there room to clone?, the test only works if the maxCloneCount isn't unlimited
				if(newCloneIndex >= this.dragObject.maxCloneCount && this.dragObject.maxCloneCount != -1){ 
					//already maxed out
					this.dragObject = dhNull;
					
					//too many maybe grab last one?
					return false; 
				}

				//we're good to go, make our clone.
				var tmpDHClone = dh.dragObject.cloneDH( dh.dragObject.id + "_clone_" + newCloneIndex , true, hidden + draggable);
				
				//move it over the beginning element
				tmpDHClone.moveTo( dsx , dsy );
				
				//if something went wrong, exit
				if( !tmpDHClone ) return false; 
				
				//setup our clone to act properly
				tmpDHClone.dragDrop = true;
				tmpDHClone.cloneOnDrag = false; //this is where we would test for clone chaining
				tmpDHClone.maxCloneCount = -1;
				tmpDHClone.alwaysOnTop = true;
				tmpDHClone.setParent('canvas');
				
				//add the clone to the clone parent's clone list.
				this.dragObject.clones[ newCloneIndex ] = tmpDHClone;
				
				//dim the parent element, so it appears like we're about to drag,
				//because we are.
				//this.dragObject.setOpacity(70); 
				
				//set our clone as the new drag object.
				this.dragObject = tmpDHClone;
				
			} else {		
				//we're removing it from it's parent... see if it was dropped here before
				//and let the dropParent know we're taking it away
				if(this.dragObject.dropParent != dhNull) {
					var dragParent = this.dragObject.dropParent;
					this.dragObject.style.position = 'absolute';
					this.dragObject.setParent('canvas');
					this.dragObject.moveTo(dsx , dsy );
					dragParent.droppedItems.splice( 
						indexOf ( dragParent.droppedItems, this.dragObject ),
						1
					);
					this.dragObject.dropParent = dhNull;
				}
				
				//bring it down to a chilled( drag ) opacity.
				this.dragObject.setOpacity(60);
			}

			//on the first move, store it's orignal position, so we can tween back later.
			if(this.dragObject.dragStartX == dhNull){
				this.dragObject.dragStartX = dsx;
				this.dragObject.dragStartY = dsy;
			}
		}

		//for draggable objects only
		if(this.dragObject.draggable){
			//get the position of the mouse cursor over the object
			this.offsetX = (this.event.offsetX || this.event.layerX);
			this.offsetY = (this.event.offsetY || this.event.layerY);
			this.mouseStartX = this.mouseX;
			this.mouseStartY = this.mouseY;

			this.objStartX = this.dragObject.x;
			this.objStartY = this.dragObject.y;

			//we're dragging
			this.isDragging = (this.dragObject.dragDrop) ? false : true; //true unless we're waiting to begin dragdrop
			this.dragObject.bringToFront();
			
			//don't let us accidently select text underneath
			//don't drag an image
			//possibly for IE only?
			dh.stopEvent(e);
			return false;
		}
		if(!this.dragObject.dragDrop && !this.dragObject.draggable) this.dragObject = dhNull; //if this object means nothing then clear it;s refrence
	},

	event_mouseMove : function (e) {
		//update general mouse movement stats
		this.mouseX = this.event.pageX || this.event.clientX + this.scrollLeft;
		this.mouseY = this.event.pageY || this.event.clientY + this.scrollTop;

		//test to see if we should start dragging
		if(	(this.dragObject && !this.isDragging) &&
			(Math.abs(this.mouseStartX - this.mouseX) > 10 ||
			Math.abs(this.mouseStartY - this.mouseY) > 10)){
			
			//are we a clone?
			if(this.dragObject.cloneParent != dhNull){
				this.dragObject.show();
				
				//only dim the CloneParent if this is the first drag of the clone.
				if( !this.dragObject.dropParent ) this.dragObject.cloneParent.setOpacity(20);
				//this.dragObject.setOpacity(100);
			} else {
			}
			this.isDragging = true;
			this.dragObject.draggable = true;
			this.dragObject.style.position = 'absolute';
			this.dragObject.setParent('canvas');
			this.dragObject.obj.className += ' dragSpace';
		}

		if(this.isDragging) { //are we atually dragging?
			this.doDrag();
			this.dragObject.event_onDrag(e);		//trigger the drag event for the object;
			if(this.onDrag != dhNull) { this.onDrag(e); }			//trigger the global drag event
			//don't let us accidently select text underneath? this may not be necessary
			this.stopEvent(e);
		}

		//call our callbacks
		for(var evKey in this.mouseMoveEvents)	{
			var callback = this.mouseMoveEvents[evKey];
			callback(e);
		}

		return (!this.isDragging); //return false for dragging, so events don't go too far
	},

	addMouseMoveEvent : function (eventKey, action){
		this.mouseMoveEvents[eventKey] = action;
	},

	removeMouseMoveEvent : function (eventKey){
		delete this.mouseMoveEvents[eventKey];
	},

	doDrag : function () {
		//get the distance we traveled fro mthe start of the drag
		var x = parseInt(this.mouseX - this.mouseStartX ) + parseInt(this.objStartX);
		var y = parseInt(this.mouseY - this.mouseStartY ) + parseInt(this.objStartY);

		//test for offset max and min
		if(this.dragObject.maxOffsetUp != dhNull) {
			if(this.dragObject.defY + y < this.dragObject.maxOffsetUp) {
				y = parseInt(this.dragObject.defY) + parseInt(this.dragObject.maxOffsetUp);
			}
		}
		if(this.dragObject.maxOffsetLeft != dhNull) {
			if(this.dragObject.defX + x < this.dragObject.maxOffsetLeft) {
				x = parseInt(this.dragObject.defX) + parseInt(this.dragObject.maxOffsetLeft);
			}
		}
		if(this.dragObject.maxOffsetRight != dhNull) {
			if(this.dragObject.defX + x > this.dragObject.maxOffsetRight) {
				x = parseInt(this.dragObject.defX) + parseInt(this.dragObject.maxOffsetRight);
			}
		}
		if(this.dragObject.maxOffsetDown != dhNull) {
			if(this.dragObject.defY + y > this.dragObject.maxOffsetDown) {
				y = parseInt(this.dragObject.defY) + parseInt(this.dragObject.maxOffsetDown);
			}
		}

		if(this.dragObject.captureToParent){
			if(y < 0) y = 0;
			if(x < 0) x = 0;
			if(x + this.dragObject.w > getInnerW(this.dragObject.obj.offsetParent) )
				x = getInnerW(this.dragObject.obj.offsetParent) - this.dragObject.w;
		}

		//only apply values that apply
		if( !this.dragObject.vertical ) this.dragObject.X(x);
		if( !this.dragObject.horiz) 	this.dragObject.Y(y);
		
		if(this.dragObject.onDrag) this.dragObject.onDrag();
	},

	event_mouseUp : function (e) {
		
		//if we were dragging, now we're dorpping
		if(this.isDragging) {
			
			//trigger the drop event for the object;
			if ( !this.dragObject.invoke("Drop") ) return;
			
			//trigger the global drop event
			if( !this.invoke('Drop') ) return;
			
			if(this.dragObject.dragDrop){ //a drag and drop object
				//did we land on anything?
				var xover = 0;
				var yover = 0;
				var dropTarget = dhNull;
				
				if( dh.dropZones ){
					this.dragObject.getWH();
					var dropZones = dh.dropZones
					for(var i = 0; i < dropZones.length; i++){
						testObj = dropZones[i];
						xover = parseInt(testObj.getW() - Math.abs(this.dragObject.getAbsX() - testObj.getAbsX()));
						yover = parseInt(testObj.getH() - Math.abs(this.dragObject.getAbsY() - testObj.getAbsY()));
						if(xover > 0 && yover > 0){ //we're on top of something!
							if ( xover * yover >= (this.dragObject.getW() * this.dragObject.getH())/ 2 ) {
								//it's the first majority we've seen
								//untill further notice this is all we need.
								dropTarget = testObj;
							}
						}
					}
				}

				//this is a workaround for simplicity, prevent errors on the line after,
				//and ensures the object is returned to it's respectful owner even if there is no
				//element or if the drophandler rejects our object				
				if( dropTarget == dhNull ) dropTarget = { dropElement : function ( e ) { return false; } };
				
				if( dropTarget.dropElement( this.dragObject ) ){
					this.stopEvent();
				} else {
					//we got an error (false ) from the dropElementFunction
					//delete our floater
					this.dragObject.dragDrop = false;
					this.dragObject.draggable = false;
					this.dragObject.destroyAtParent();
				}
			}
		}
		
		if( this.dragObject ){
			this.isDragging = false; //we're done
			this.dragObject.obj.className = this.dragObject.obj.className.replace( /(\dragSpace)|(dragSpace)/gi, "");
			this.dragObject = dhNull;
		}
		//even if we're not dragging
		//we could have mouseup events
		for(var evKey in this.mouseUpEvents)	{
			var callback = this.mouseUpEvents[evKey];
			callback(e);
		}
	},

	addMouseUpEvent : function (eventKey, action){
		this.mouseUpEvents[eventKey] = action;
	},

	removeMouseUpEvent : function (eventKey){
		delete this.mouseUpEvents[eventKey];
	},



	/*--------------
		Mouse Wheel
	---------------*/
		event_mouseWheel : function(){
		        var delta = 0;
                var event = this.event;
				
		        if (event.wheelDelta) { /* IE/Opera. */
		                delta = event.wheelDelta/120;
		                /** In Opera 9, delta differs in sign as compared to IE. */
		                if (window.opera) delta = -delta;
		        } else if (event.detail) { 
						/** Mozilla case. */
		                /** In Mozilla, sign of delta is different than in IE.
		                 * Also, delta is multiple of 3. */
		                delta = -event.detail/3;
		        }
		        /** If delta is nonzero, handle it.
		         * Basically, delta is now positive if wheel was scrolled up,
		         * and negative, if wheel was scrolled down.
		         */
				//console.log( this.event );
				if( this.eventTargetElement){
					var tmpObj = this.eventTargetElement;
					//look for elements with scrollbars
					while( tmpObj ){
						if( hasScrollBar(tmpObj) ){
							break;
						}
						tmpObj = tmpObj.offsetParent;
					}
					if(tmpObj) {
				        /** Prevent default actions caused by mouse wheel.
				         * That might be ugly, but we handle scrolls somehow
				         * anyway, so don't bother here..
				         */
						if( (delta > 0 && !canScrollUp( tmpObj ) ) ||
							 ( delta < 0 && !canScrollDown( tmpObj ) ) ){
							this.stopEvent();
					        if (event.preventDefault) event.preventDefault();
							event.returnValue = false;
						}
					}
				}

		},

	/*--------------
		Scrolling
	---------------*/
		event_scroll : function (e){
			var scrollValues = getPageScroll();
			
			this.scrollLeft = scrollValues[0]
			this.scrollTop = scrollValues[1];
			
			//call our callbacks
			for(var evKey in this.scrollEvents)	{
				var callback = this.scrollEvents[evKey];
				if( !callback(e) ) return false;
			}
		},

		addScrollEvent : function (eventKey, action){
			this.scrollEvents[eventKey] = action;
		},

		removeScrollEvent : function (eventKey){
			delete this.scrollEvents[eventKey];
		}
}


/********************************************************************************************
// DHTML Object Wrapper for dom model
 *
 * Used on a per object basis
 * Managed by the DH object
 *
********************************************************************************************/
//	var obj = new dhObj( 'domElementID' );
//
//
//
function DHNode( objid ){
	//check for lazt init
	if(objid){
		//some instance associated arrays
		this.scriptedObjects = 	[];
		this.clones = 			[];
		this.droppedItems = 	[];
		this.inEvents = 		{};
		
		this.bind( objid );
	}
}

	//********************************************************************************************
	// DHTML Element Object specific functions
	//********************************************************************************************
	DHNode.prototype = {

		name: 			null,
		id: 			null,
		/*
		 * Moved to constructor for instance problems
		clones:			[],
		droppedItems:	[],
		inEvents:		{},
		*/
		dhParent: 		dhNull,
		allowInitialize:true,
		alwaysOnTop:	false,
		centerOnShow: 	false,

		//---------------
		// HTML Element Info
		//----------------
			isFormElement: 	false,
			formElementType:dhNull,

		//--------------
		// Graphical
		//--------------
			cursor:		null,
			fadeIn: 	false,
			fadeOut: 	false,
			visible: 	null,
			opacity: 	100,

		//--------------
		// Positioning
		//--------------
			dragStartX: dhNull,
			dragStartY: dhNull,
			defAbsX: 	dhNull,
			defAbsY: 	dhNull,
			defX: 		dhNull,
			defY:		dhNull,
			defZ: 		dhNull,
			absX: 		dhNull,
			absY: 		dhNull,
			x: 			dhNull,
			y: 			dhNull,
			z: 			dhNull,
			positioning:dhNull,

		//--------------
		// Sizing
		//--------------
			width: 	dhNull,
			height: dhNull,
			defH: 	dhNull,
			defW: 	dhNull,
			h: 		dhNull,
			w: 		dhNull,

		//-------------
		// Movement
		//-------------
			maxOffsetUp: 	dhNull,
			maxOffsetDown: 	dhNull,
			maxOffsetLeft: 	dhNull,
			maxOffsetRight: dhNull,
			vertical: 		false,
			horiz: 			false,

		//--------------
		// Drag & Drop
		//--------------
			cloneParent: 		dhNull,
			dropParent: 		dhNull,
			dragDrop: 			false,
			dropZone: 			false,
			dragGroup:			null,
			dragHandle: 		dhNull,
			draggable: 			false,
			maxCloneCount: 		-1,
			maxDropCount: 		-1,
			dropCount: 			0,
			cloneOnDrag: 		false,
			captureToParent:	false,

		//***************
		//Outgoing events
		//***************/
			//--------------------------
			// Custom Graphical Events
			//--------------------------
				onShow : 	dhNull,
				onHide : 	dhNull,

			//--------------------------
			// Custom Drag & Drop Events
			//--------------------------
				onGrab : dhNull,
				onDrag : dhNull,
				onDrop : dhNull,
				onLand : dhNull,

			//--------------------------
			// managed dom events
			//--------------------------
				onFocus : 	dhNull,
				onBlur : 	dhNull,
				onMove : 	dhNull,
				onResize : 	dhNull,
				onScroll : 	dhNull,

			//--------------
			// Mouse Tracking?
			//--------------
				onClick: 		dhNull,
				onDblClick: 	dhNull,
				onMouseOver: 	dhNull,
				onMouseDown: 	dhNull,
				onMouseMove: 	dhNull,
				onMouseUp: 		dhNull,
				onMouseOut: 	dhNull,
				onMouseWheel: 	dhNull,

		//------------------------------------
		// Bind to an HTML Element
		//
		//	Pre: objid is a unique element id
		//	Post: this.obj and this.style
		//			are valid
		//	error:	return false;
		//------------------------------------
		bind: function( objid, autoInit ){
			if(autoInit == dhNull ) autoInit = true;
			try {
				this.obj = getObject(objid);
				this.style = this.obj.style;
				this.id = objid;
				this.name = objid;
			}
			catch(e){
				alert("Cannot bind: " + objid + "\n" + dumpObj(e));
				return dhNull;
			}
			if( autoInit ) this.initialize( true, true);
		},

		extend : function( src ){
			for(var a in src){ this[a] = src[a]; }
		},

		retract : function( src ){
			for(var a in src){try{ delete this[a];} catch(e){  } }
		},

		//------------------------
		// Initialization
		//------------------------
		initialize : function(resetDefaults, orignalInit){
			if(orignalInit == dhNull) {
				originalInit = false;
				if(this.allowInitialize == false) return;
			}

			if( orignalInit ) {

				this.findDHParent();
				if( this.dhParent) {
					//console.log( this.id  + " - " + this.dhParent.id );

					for(var i = 0 ; i < this.dhParent.scriptedObjects.length; i++ ){
						//if this element is a decendant of the scripted object something is wrong , that should be our parent

						//if the scripted object is a child of ourself then add it to our list of scipted objects and removeit from our parent
						//console.log( this.dhParent.scriptedObjects[i] );
						var tmpSObj = this.dhParent.scriptedObjects[i];
						if( tmpSObj.isDescendantOf( this.obj ) ) {
							var sObj = this.dhParent.removeScriptedObject( tmpSObj );
							//console.info( "pulled - " + sObj.id );
							this.addScriptedObject( sObj );
						} else {
						}
					}
					this.dhParent.addScriptedObject( this );
				}

			}

			//removed from the not working dhtml left it here for a reminder
			//clear inline styles so css kicks in
			//this.obj.setAttribute("style", "");

			//---------------
			// HTML Element Info
			//----------------
			this.getHTMLType();

			//--------------
			// Graphical
			//--------------
			this.cursor = this.getStyle("cursor");
			this.visible = (this.getStyle("visibility") == 'hidden') ? false : true;
			//this.opacity = 100; //can't do this one

			//--------------
			// Positioning
			//--------------
			this.absX = parseInt(this.getAbsX());
			this.absY = parseInt(this.getAbsY());
			this.x = parseInt(this.getX());
			this.y = parseInt(this.getY());
			this.z = parseInt(this.style.zindex);
			if(resetDefaults){
				this.defAbsX = this.absX;
				this.defAbsY = this.absY;
				this.defX = this.x;
				this.defY = this.y;
				this.defZ = this.z;
			}

			//are we relative or absolute
			this.positioning = (this.defX != this.defAbsX) ? POS_RELATIVE : POS_ABSOLUTE;

			//--------------
			// Sizing
			//--------------
			this.width = (this.style.pixelWidth) ? this.style.pixelWidth : this.style.width;
			this.height = (this.style.pixelHeight) ? this.style.pixelHeight : this.style.height;
			this.getWH();
			if(resetDefaults){
				this.defH = this.h;
				this.defW = this.w;
			}
	},

		//------------------------
		// Debugging
		//------------------------
		dump : function (html) { //set html to true when writing to a document
			var newline;
			html == true ? newline = "<br>\n" : newline = "\n";

			output = "object name: " + this.name +  newline;
			output += "positioning: " + this.positioning +  newline;
			output += "defX: " + this.defX +  newline;
			output += "defY: " + this.defY + newline;
			output += "defZ: " + this.defZ + newline;
			output += "defAbsX: " + this.defAbsX +  newline;
			output += "defAbsY: " + this.defAbsY + newline;
			output += "x: " + this.x + newline;
			output += "y: " + this.y + newline;
			output += "z: " + this.z + newline;
			output += "defW: " + this.defW + newline;
			output += "defH: " + this.defH + newline;
			output += "w: " + this.w + newline;
			output += "h: " + this.h + newline;
			output += "maxOffsetUp: " + this.maxOffsetUp + newline;
			output += "maxOffsetDown: " + this.maxOffsetDown + newline;
			output += "maxOffsetLeft: " + this.maxOffsetLeft + newline;
			output += "maxOffsetRight: " + this.maxOffsetRight + newline;
			return output;
		},

		dumpCSS : function (html) { //more on this later
			var newline;
			var output = "";

			html == true ? newline = "<br />\n" : newline = "\n";
			//for(var i = 0; i < this.style.length; i++) {
				//output +="sdsd" +  this.getStyle('position');
				//output += ": " + this.style[i].cssText +  newline;
			//}
			return output;
		},

		error : function(e, source){
			dh.nodes.test.write("Error: " + e + "<br /><br />" + source + "<br /><br />" + this.dump(true));
		},

		//------------------------
		// Interactivity Functions
		//------------------------
		setDraggable : function(onoff){
			this.draggable = onoff;
		},

		setHandle : function( handle ){
			handle.onGrab = Function( "dh.dragObject = dh.nodes." + this.id + "; return dh.dragObject.invoke('Grab');" );
			//this.__mousedown = Function("return false;"); //stop mouse event propogation
			this.dragHandle = handle;
		},

		removeHandle : function( ){
			this.dragHandle.onGrab = "";
			this.dragHandle = dhNull;
		},


		//-----------------------
		// Event Handling
		//-----------------------
		invoke : function(ev, param){
			try { return this['on' + ev](param); }
			catch (ex){
				
			}
			return true;
		},

		addDOMEvent : function(ev, callback) {
			this.inEvents[ ev ] = callback;
			if (this.obj.addEventListener) { this.obj.addEventListener(ev, 		callback, false );}
			else if (this.obj.attachEvent) { this.obj.attachEvent('on' + ev,	callback); }
		},

		removeDOMEvent : function(ev) {
			var callback = this.inEvents[ev];
			if (this.obj.removeEventListener) { this.obj.removeEventListener( ev, callback , false ); }
			else if (this.obj.detachEvent) { 	this.obj.detachEvent( 'on' + ev, callback ); }
		},

		bindDOMEvents : function(){
			var dhobj = this;
			this.addDOMEvent('click',		function (e) { return dhobj['__click'](e); });
			this.addDOMEvent('dblclick',	function (e) { return dhobj['__dblclick'](e); });
			this.addDOMEvent('mouseover',	function (e) { return dhobj['__mouseover'](e); });
			this.addDOMEvent('mousedown',	function (e) { return dhobj['__mousedown'](e); });
			this.addDOMEvent('mousemove',	function (e) { return dhobj['__mousemove'](e); });
			this.addDOMEvent('mouseout',	function (e) { return dhobj['__mouseout'](e); });
			this.addDOMEvent('focus',		function (e) { return dhobj['__focus'](e); });
			this.addDOMEvent('blur',		function (e) { return dhobj['__blur'](e); });
			this.addDOMEvent('scroll',		function (e) { return dhobj['__scroll'](e); });
		},

		unbindDOMEvents : function(){
			this.removeDOMEvent('click');
			this.removeDOMEvent('dblclick');
			this.removeDOMEvent('mouseover');
			this.removeDOMEvent('mousedown');
			this.removeDOMEvent('mousemove');
			this.removeDOMEvent('mouseout');
			this.removeDOMEvent('focus');
			this.removeDOMEvent('blur');
			this.removeDOMEvent('scroll');
		},

		removeDHEvents : function (){
			//--------------------------
			// Custom Graphical Events
			//--------------------------
				this.onShow = 	dhNull;
				this.onHide = 	dhNull;

			//--------------------------
			// Custom Drag & Drop Events
			//--------------------------
				this.onGrab = dhNull;
				this.onDrag = dhNull;
				this.onDrop = dhNull;
			//--------------------------
			// managed dom events
			//--------------------------
				this.onFocus = 	dhNull;
				this.onBlur = 	dhNull;
				this.onMove = 	dhNull;
				this.onResize = dhNull;
				this.onScroll = dhNull;

			//--------------
			// Mouse Tracking?
			//--------------
				this.onClick =  	dhNull;
				this.onDblClick = 	dhNull;
				this.onMouseOver = 	dhNull;
				this.onMouseDown = 	dhNull;
				this.onMouseMove = 	dhNull;
				this.onMouseUp = 	dhNull;
				this.onMouseOut = 	dhNull;
				this.onMouseWheel = dhNull;
		},
		//******************************************************
		// Incomming Events
		//******************************************************
			__click : function (e){
				try{
					if(!e) e = window.event;
					dh.event = e;
					return this.invoke('Click');
				} catch (ex){}
				return true;
			},
			__dblclick : function (e){
				try{
					if(!e) e = window.event;
					dh.event = e;
					return this.invoke('DblClick');
				} catch (ex){}
				return true;
			},
			__mouseover : function (e) {
				try{
					if(!e) e = window.event;
					dh.event = e;
					return this.invoke('MouseOver');
				} catch (ex){}
				return true;
			},
			__mousedown : function (e){
				if(dh.dragObject != dhNull) return false;
				if(!e) e = window.event;
				dh.event = e;
				if( !this.invoke('MouseDown') ) return false;
				if( this.dragHandle ) return false;
				dh.dragObject = this;
				return dh.event_mouseDown(e);
			},
			__mousemove : function (e){
				try{
					if(!e) e = window.event;
					dh.event = e;
					return this.invoke('MouseMove');
				} catch (ex){}
				return false;
			},
			__mouseout : function (e){
				try{
					if(!e) e = window.event;
					dh.event = e;
					return this.invoke('MouseOut');
				} catch (ex){}
				return true;
			},
			__focus : function (e){
				try{
					if(!e) e = window.event;
					dh.event = e;
					return this.invoke('Focus');
				} catch (ex){}
				return true;
			},
			__blur : function (e){
				try{
					if(!e) e = window.event;
					dh.event = e;
					return this.invoke('Blur');
				} catch (ex){}
				return true;
			},
			__scroll : function (e){
				try{
					if(!e) e = window.event;
					dh.event = e;
					return this.invoke('Scroll');
				} catch (ex){}
				return true;
			},

		//*****************************************************
		//	Outgoing Events events (page scripting)
		//*****************************************************
			event_onGrab : function (e){
				return this.invoke("Grab");
			},
			event_onDrag : function (e){
				return this.invoke("Drag");
			},
			event_onDrop : function (e){
				return this.invoke("Drop");
			},

		//------------------------
		// DOM Interaction
		//------------------------
		getHTMLType : function(){
			switch(this.obj.tagName.toLowerCase()){
				case HTML_ANCHOR:
					this.elementType = HTML_ANCHOR;
					break;
				case HTML_BODY:
					this.elementType = HTML_BODY;
					break;
				case HTML_BUTTON:
					this.isFormElement = true;
					this.elementType = HTML_BUTTON;
					break;
				case HTML_DIV:
					this.elementType = HTML_DIV;
					break;
				case HTML_FORM:
					this.elementType = HTML_FORM;
					break;
				case HTML_IFRAME:
					this.elementType = HTML_IFRAME;
					break;
				case HTML_IMAGE:
					this.elementType = HTML_IMAGE;
					break;
				case HTML_INPUT:
					this.isFormElement = true;
					this.elementType = HTML_INPUT;
					break;
				case HTML_ORDEREDLIST:
					this.elementType = HTML_ORDEREDLIST;
					break;
				case HTML_PARAGRAPH:
					this.elementType = HTML_PARAGRAPH;
					break;
				case HTML_SPAN:
					this.elementType = HTML_SPAN;
					break;
				case HTML_TEXTAREA:
					this.isFormElement = true;
					this.elementType = HTML_TEXTAREA;
					break;
				case HTML_UNORDEREDLIST:
					this.elementType = HTML_UNORDEREDLIST;
					break;
				default:
					break;
			}
		},

		isDescendantOf : function(distantRelative){
			tmpObj = this.obj;
			while(tmpObj = tmpObj.parentNode)
				if(tmpObj == distantRelative) return true;
			return false;
		},

		//------------------------
		// DHNode specific
		//------------------------
		addScriptedObject: function ( object ){
			if( !isObject( object) ) object = dh.$(object);
			if(object == false) return;
			this.scriptedObjects.push(object);
		},

		removeScriptedObject: function ( object ){
			var idx = false;

			for(var i = 0; i < this.scriptedObjects.length; i++){
				//console.log(this.scriptedObjects[i].id + " - " + object.id);
				//if( this.scriptedObjects[i].id == object.id ){
				//	idx = i;
				//	break;
				//}
			}

			if( idx != false){
				//console.log(idx);
				return this.scriptedObjects.splice( idx , 1 );
			} else {
				
			}
		},

		//------------------------------
		// Drag & Drop Cloning Functions
		//------------------------------
		/**
		 * Requests an element to accept another
		 * to be dropped in.
		 * @param {HTMLElement} 	element being dropped
		 * @return (Boolean)		true on success
		 */
		dropElement : function ( element ){
			try{
				//make sure we're not already full
				if( this.maxDropCount >= this.droppedItems.length) return false;

				//invoke the callback, and exit if they request so.
				//if the land function decides to accept the object,
				//it also must take case of any graphical changes and control of the dragElement
				//we will onlt take care of refrences here.
				
				//this function previously did handle the setting of parents but due to functinality requirements
				//it was handed over to the onLand handlers
				if( !this.invoke( 'Land' , element ) ) return false;			
				
				element.dropParent = this;
				this.droppedItems[this.droppedItems.length] = element;
				this.dropCount = this.droppedItems.length;

				if( element.cloneParent ) element.cloneParent.setOpacity(100);

			} catch (ex){
				return false;
			}
			return true;
		},

		removeFromDom : function(){
			try{
				//pull it from the dom
				this.obj.parentNode.removeChild(this.obj);
		
				//clean up our old DHParent
				if( this.dhParent ) this.dhParent.removeScriptedObject( this );
			} catch ( ex ){
				
			}

		},

		cloneDH : function(newId, cloneChildrenToo, dhParams){
			var obj = this.obj.cloneNode(cloneChildrenToo); //create the dupe object
 			obj.id = newId; 								//set the DOM id - can't be a duplicate
 			document.body.appendChild(obj); 				//insert it where it can be found
 			var tmpNode = dh.addObject(obj.id, dhParams); 				//add it to the lib
 			if( this.getValue() )  tmpNode.setValue(this.getValue());
 			tmpNode.cloneParent = this; 					//set this dhObj as the parent
 			if( this.dragGroup ) tmpNode.dragGroup = this.dragGroup;
 			return tmpNode; 								//return the ref
		},

		setParent : function(newParentID){
			try{
				//move and exit on failure
				if( !setParent(this.obj, newParentID) ) return false;
			
				//clean up our old DHParent
				if( this.dhParent ) this.dhParent.removeScriptedObject( this );
				
				//look for a new DHParent
				var newDHParent = this.findDHParent();
				
				//if we found a new one then talk to it
				if( newDHParent ) {
					this.dhParent = newDHParent;
					this.dhParent.addScriptedObject( this );
				}
			}catch(ex){
				
			}
			return true;
		},

		insertBefore : function(  adjacentElement ){
			//return setParent(this.obj, newParentID);
		},
		
		insertAfter : function( adjacentElement){
			//return setParent(this.obj, newParentID);
		},

		findDHParent : function (){
			var tmpId = "";
			var tmpObj = this.obj;
			while(tmpObj = tmpObj.parentNode){
				tmpId = tmpObj.id || tmpObj.name;
				if( dh.$(tmpId) ){
					this.dhParent = dh.$(tmpId);
					return dh.$(tmpId);
				}
			}
			return false;
		},

		setDHParent : function(newDHParent){
			if( this.dhParent ) this.dhParent.removeScriptedObject( this );

			var elementRef = this.obj.parentNode.removeChild(this.obj);
			newDHParent.obj.appendChild(elementRef);
			this.dhParent = newDHParent;

			this.dhParent.addScriptedObject( this );
		},

		clean : function (){
			try{
				while( this.scriptedObjects.length ){
					var t = this.scriptedObjects.pop();
					//console.log("destroying scripted object - ", t);
					t.dhParent = null; //so it doesn't try to remove it from the parent , we already popped it
					t.destroy();
				}
				this.scriptedObjects = [];
			} catch(e){
				
			}
		},

		purge : function (){
			this.clean();
			//console.log("purging " + this.id);
			this.obj.innerHTML = "";
			this.obj.scrollTop = 0;
		},

		destroy : function(){
			try{
				this.clean();
				this.unbindDOMEvents();
				this.removeDHEvents();
				dh.detachNode(this.id);
				this.obj.parentNode.removeChild(this.obj);
				if(this.dhParent) this.dhParent.removeScriptedObject(this);
			} catch (ex) {
				//alert(dumpObj(ex));
				//console.error("Cannot destroy - " + this.id + " - %1 - %2", ex, this);
			}
		},

		//------------------------
		// Style Functions
		//------------------------
		setCursor : function ( cursor ){
			this.cursor = cursor;
			this.obj.style.cursor = cursor;
		},

		setStyle : function(name, value) {
			eval('this.obj.style.' + name + ' = value;');
		},

		clearStyle : function ( style ){
			try{ delete this.obj.style[ style ]; }
			catch ( ex ){  return false;}
			return true
		},

		getStyle : function (strCssRule){
			var strValue = "";
			if(document.defaultView && document.defaultView.getComputedStyle){
				try{
					strValue = document.defaultView.getComputedStyle(this.obj, "").getPropertyValue(strCssRule);
				}catch(e){}
			}
			else if(this.obj.currentStyle){
				try{
					strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
						return p1.toUpperCase();
					});
					strValue = this.obj.currentStyle[strCssRule];
				}
				catch(e){
					// Used to prevent an error in IE 5.0
				}
			}
			return strValue;
		},
/*
		getStyle : function (styleProp)	{
			var y;
			try{
				if (this.obj.currentStyle)
					y = this.obj.currentStyle[styleProp];
				else if (window.getComputedStyle)
					y = document.defaultView.getComputedStyle(this.obj,null).getPropertyValue(styleProp);
			} catch (e){
			}
			alert(y);
			if (y == dhNull){
				styleProp = toJavaStyle(styleProp);
				try{
					y = eval("this.style." + styleProp);
					alert("this.style." + styleProp);
				} catch (e) {
					y = "";
				}
			}
			return y;
		},
*/
		//------------------------
		// Position Functions
		//------------------------
		//getXDistanceTo :function( obj ){
		//	var tmpObj
		//	while( )
		//},
		//getYDistanceTo :function( obj ){
		//
		//},

		getX : function (){ return this.x = getX(this.obj); },
		getY : function (){ return this.y = getY(this.obj); },
		getXY: function (){
			this.x = parseInt(this.getX());
			this.y = parseInt(this.getY());
		},
		getAbsX : function (){ return this.absX = getAbsX( this.obj ); },
		getAbsY : function (){ return this.absY = getAbsY( this.obj ); },

		//------------------------
		// Positioning Functions
		//------------------------
		X: function(value){
			try{
				if(value != dhNull && value != "NaN") {
					this.style.left = (this.x = parseInt(value)) + dh.px;
				}
			} catch (e){
				//alert(value);
			}
			return this.x;
		},
		Y: function(value){
			try {
				if(value != dhNull && value != "NaN") {
					this.style.top = (this.y = parseInt(value)) + dh.px;
				}
			} catch (e){
				//alert(value);
			}
			return this.y;
		},
		moveTo : function(x,y){
			if( !isEmpty(x) ) this.X(x);
			if( !isEmpty(y) ) this.Y(y);
			this.invoke("Move");
		},
		moveBy : function(deltaX, deltaY){ this.moveTo(this.x + deltaX, this.y + deltaY); },
		setZ : function(z) { this.style.zIndex = this.z = z; },
		bringToFront : function( forceOnTop ){
			dh.highz++;
			if( this.alwaysOnTop || forceOnTop ){
				this.setZ( dh.highz + 7000 );
			} else {
				this.setZ( dh.highz );
			}
			
			for(var i = 0; i < this.scriptedObjects.length;i++)
				if(this.scriptedObjects[i])
					this.scriptedObjects[i].bringToFront( ( this.alwaysOnTop || forceOnTop) ? true : false );
				else {
					//firebugError(this.id);
				}
			
			//this.invoke("BringToFront");
		},
			
		centerViewport: function(){
			this.moveTo(
				((dh.viewportW - this.w) / 2) + dh.scrollLeft,
				((dh.viewportH - this.h) / 2) + dh.scrollTop
				);
		},

		//------------------------
		// Sizing Functions
		//------------------------
		W : function (value) {
			try {
				if(value != dhNull && value != "NaN") {
					value = (value < 0)? 0 : value;
					this.style.width = (this.w = parseInt(value)) + dh.px;
				}
			}catch(e){
				//alert(value);
			}
			return this.w;
		},
		H : function(value) {
			try{
				if(value != dhNull && value != "NaN") {
					value = (value < 0)? 0 : value;
					this.style.height = (this.h = parseInt(value)) + dh.px;
				}
			} catch (e){
				//alert(value);
			}
			return this.h;
		},
		resizeTo : function(w,h){
			if( !isEmpty(w) ) this.W(w);
			if( !isEmpty(h) ) this.H(h);
			this.invoke("Resize");
		},
		resizeBy : function(deltaW,deltaH){	this.resizeTo(this.w + deltaW, this.h + deltaH); },

		getInnerW : function() { return getInnerW(this.obj); },
		getInnerH : function() { return getInnerH(this.obj); },
		getW : function() { return this.w = getW(this.obj); },
		getH : function() { return this.h = getH(this.obj); },
		getWH : function() {
			this.w = parseInt(this.getW());
			this.h = parseInt(this.getH());
		},

		//------------------------
		// Graphical Functions
		//------------------------
		fadeBy : function(deltaAlpha){ this.setOpacity(this.opacity + deltaAlpha); },
		setOpacity : function(opacity){
			if( !setOpacity(this.obj, opacity) ) return false;
			this.opacity = opacity; //opacity tracking
			return true;
		},
		animateFadeIn : function(){
			this.animate(
				new dh.tweenDetails(
					dhNull ,//x
					dhNull, //y
					dhNull,	//w
					dhNull, //h
					100,	//alpha
					100,	//duration
					5),	//increment
				function(obj, tweenInfo){} );
		},
		animateFadeOut : function(){
			this.animate(
				new dh.tweenDetails(
					dhNull ,//x
					dhNull, //y
					dhNull,	//w
					dhNull, //h
					0,		//alpha
					100,	//duration
					5),	//increment
				function(obj, tweenInfo){
					obj.hideNow();
				}
			);
		},

		hideBlock : function (){ return hideBlock( this.obj ); },
		showBlock : function() { return showBlock( this.obj ); },
		hideNow : function (){
			if( !hideObject( this.obj ) ) return false;
			this.visible = false;
			this.invoke("Hide");
			return true;
		},
		showNow : function() {
			if(this.fadeIn){ this.setOpacity(100); }
			if( !showObject(this.obj) ) return false;
			this.visible = true;
			this.invoke("Show");
			return true;
		},
		hide : function (){
			if(this.fadeOut){
				this.animateFadeOut();
				return;
			}
			if( !hideObject( this.obj ) ) return false;
			this.visible = false;
			this.invoke("Hide");
			return true;
		},
		show : function() {
			if(this.fadeIn){ this.setOpacity(0); }
			if( !showObject(this.obj) ) return false;
			if(this.centerOnShow) this.centerViewport();
			this.visible = true;
			if(this.fadeIn){ this.animateFadeIn(); }
			this.invoke("Show");
			return true;
		},
		disappear : function (){
			if( !invisible( this.obj ) ) return false;
			this.visible = false;
			return true;
		},
		reappear : function() {
			if(this.fadeIn){ this.setOpacity(100); }
			if( !reappear( this.obj ) ) return false;
			this.visible = true;
			return true;
		},
		
		setBgColor : function(color){ return setBgColor(this.obj, color); },
		setBgImage : function(url, options){ return setBgImage(this.obj, url, options); },

		//------------------------
		// Text Functions
		//------------------------
		write : function(text){
			if(dh.n4) {
				(d_o = this.div.document).open();
				this.obj.write(text);
				this.obj.close();
				this.getWH();
			}
			else {
				//this.style.height = 'auto';
				this.obj.innerHTML = text;
				this.getWH();
			}
		},


		//------------------------
		// Scrolling Functions
		//------------------------
		scrollTop: function( y ){
			try{
				this.obj.scrollTop = (this.scrollTop = y) + dh.px;
			} catch (ex){}
			return this.scrollTop;
		},
		scrollLeft: function( x ){
			try{
				this.obj.scrollLeft = (this.scrollLeft = x) + dh.px;
			} catch (ex){}
			return this.scrollTop;
		},
		scrollTo: function( x, y ){
			if(x != dhNull) this.scrollLeft(x);
			if(y != dhNull) this.scrollLeft(y);
			this.invoke("Scroll");
		},

		//------------------------
		// Form Element Functions
		//------------------------
		setValue : function(value){ return setValue(this.obj, value); },
		getValue : function(){ return getValue(this.obj); },
		isChecked : function(ch){ return isChecked(this.obj, ch); }, //will set checked if given and always returns the value
		radioValue : function(ch){ return radioValue(this.id, ch); }, //will set checked if given and always returns the value

		//------------------------
		// Image Functions
		//------------------------
		//alias
		setImg : function(src, whenDone){
			this.setImage( src, whenDone);
		},
		setImage : function(src, whenDone){
			this.obj.src = src;
			if( whenDone != dhNull){
				this.obj.onload = function () { whenDone(); }
			}
		},

		//----------------------------------
		//  Animations
		//----------------------------------
		destroyAtParent : function (){
			var frameDelay = 50;
			
			var htmlElement = this.obj;
			var dhNode = this;
			
			var absX = getAbsX(htmlElement);
			var absY = getAbsY(htmlElement);
			
			quickTween(
				htmlElement,
				{
					destX : this.dragStartX,
					destY : this.dragStartY,
					diffX : this.dragStartX - absX,
					diffY : this.dragStartY - absY,
					destAlpha : 0,
					diffAlpha : 100
				},
				50,
				5,
				function(){
					if( dhNode.cloneParent ) dhNode.cloneParent.setOpacity(100);
					dhNode.destroy();
				}
			);
			//for( var frame = 1; frame <= 10; frame++){
			//	setTimeout( 
			//		function (){
			//			X(htmlElement, this.dragStartX / frame);
			//			Y(htmlElement, this.dragStartY / frame);
			//			setOpacity(htmlElement, 100 / frame);
			//		}
			//	, frameDelay * frame );
			//}
			
			//setTimeout( 
			//	function (){
			//		X(htmlElement, this.dragStartX);
			//		Y(htmlElement, this.dragStartY);
			//		setOpacity(htmlElement, 0);
			//	}
			//, frameDelay * frame );
			/*
			this.animate(
					new dh.tweenDetails(
						this.dragStartX, //x
						this.dragStartY, //y
						dhNull,	//w
						dhNull, //h
						0,		//alpha
						.5,		//duration
						10),	//increment
					function(obj, tweenInfo){
						if( obj.cloneParent ) obj.cloneParent.setOpacity(100);
						obj.destroy();
					}
				);
			*/
		},
		
		animate : function(tweenObj, callBack, newThread){
			var myself = this;
			
			if( !newThread ){
				setTimeout(function(){ myself.animate(tweenObj, callBack, true); },0);
				return;
			}
			
			var steps = [];
			var current = 0;

			//this.getXY();
			this.getWH();
			while(current < tweenObj.incrementCount ) {
				steps.unshift( {
					x : (tweenObj.x != dhNull) ? this.x + ( parseInt( (tweenObj.x - this.x) / tweenObj.incrementCount ) * current ) : dhNull,
					y : (tweenObj.y != dhNull) ? this.y + ( parseInt( (tweenObj.y - this.y) / tweenObj.incrementCount ) * current ) : dhNull,
					w : (tweenObj.w != dhNull) ? this.w + ( parseInt( (tweenObj.w - this.w) / tweenObj.incrementCount ) * current ) : dhNull,
					h : (tweenObj.h != dhNull) ? this.h + ( parseInt( (tweenObj.h - this.h) / tweenObj.incrementCount ) * current ) : dhNull,
					opacity : (tweenObj.alpha != dhNull) ? this.opacity + ( parseInt( (tweenObj.alpha - this.opacity) / tweenObj.incrementCount ) * current ) : dhNull,
					delay : 	parseInt( tweenObj.duration / tweenObj.incrementCount )
				} );
				current++;
			}
			tweenObj.steps = steps;
			dh.tweening = true;
			tween( this , tweenObj, callBack);
		}
	} //end of dhObj Class Definition

function dhScrollTo(dhId,parentNode){
	var node = null;
	var scrollDiv = getObject(parentNode);
	var scrollTop = 0;
	if(!(node = dh.$(dhId))){
		node = dh.addObject(dhId);
	}
	scrollTop = node.getAbsY() - dh.nodes.dhWin_vault.getAbsY();
	scrollDiv.scrollTop = scrollTop - 20;
}

var progressCheckCounter = 0; // just keeping track of how many times we checked the file status



function startUpload( treeId ,formName){
	if(!formName) var formName = 'frmVaultUpload';
	var frm = getObject(formName);
	var iframe = getObject('remoteIFrame');
	var tree = null;
	if(treeId){
		tree = getObject(treeId).tree;
	}
	// make sure we got some files -- use our files counter
	var fileCtrName = 'TOTAL_FILES'
	if(formName != 'frmVaultUpload'){
		if(formName == 'frmPhotoUpload' )
			fileCtrName = 'TOTAL_PHOTO_FILES';
		else
			fileCtrName = 'TOTAL_FORSALE_FILES';
	}
	var filesCtr = getObject(fileCtrName);
	if (formName == "quickAvatarUploadForm" || (filesCtr && filesCtr.value > 0) ){
			frm.submit();
		// reset the upload bar
		// reset the upload bar
		/*var bar = getObject('progressBarFront');
		var barPct = getObject('progressPct');
		bar.style.width = "0%";
		barPct.innerHTML = 'Starting...';
		if(!dh.nodes.uploadProgressWrapper){
			dh.addObject("uploadProgressWrapper",hidden);
		}
		dh.nodes.uploadProgressWrapper.show();
		dh.nodes.uploadProgressWrapper.centerViewport();
		dh.nodes.uploadProgressWrapper.bringToFront()
		dh.__scroll(); //movethe bar and the browse icon
		progressCheckCounter = 0; // reset our counter
		updateUploadProgress(tree,formName);*/
	}else{
		//alert('You do not have any files to upload. Please add some files and try again.');
		return true;
	}
}

// just change the src of the iframe object
function cancelVaultUpload(){
	dh.nodes.uploadProgressWrapper.hide();
	var iframeObj = getObject('remoteIFrame');
	//iframeObj.src = '';
}

function vaultUploadResult(serverResponse){
	var responseObj = JSON.parse(unescape(serverResponse));
	dh.nodes.uploadProgressWrapper.hide();
	if (responseObj.result == 'true'){
		//getData('Vault');
		//getData('Vaults');
		//showMsg('Success', 'All your vault items have been uploaded.');
		progressCheckCounter = 0; // reset our counter
	}else{
		//showMsg('Upload Failure', 'ERROR: ' + responseObj.errors);
		alert(getObject("remoteIFrame").innerHTML);
	}
}

function updateUploadProgress( tree ,formName){
	var uploadKey = getObject('progress_key');
	ajax.post('/api/fileupload/up_status',
		{
			f: 'progress',
			APC_UPLOAD_PROGRESS: uploadKey.value
		},
		function (connectionInstance){ //on success

			var r = connectionInstance.responseObject;
			if (!r || r["Error"]){
				dh.nodes.uploadProgressWrapper.hide();
				if (tree) { client.windowFunctions.vault.buildVaultMan(tree); }
				if(r["Error"])
					alert(r["Error"]);
				return;
			}

			// upload is too big or some other error -- hide the progress window & let php handle the error
			// or we can handle the error here...HMmMmMmm....?
			if (r.result == 'false' || r.serverResponse == 'false' || r.serverResponse == false){
				//showMsg('Failure', 'Your upload has failed because: <br />' + r.errors);
				dh.nodes.uploadProgressWrapper.hide();
				deleteCookie("allow_upload", "/");
			}else{
				// prevent "undefined" vals
				var totalSize = isEmpty(r.total)? 0 : r.total;
				var currentUploaded = isEmpty(r.current)? 0 : r.current;
				var rate = isEmpty(r.rate)? 0 : r.rate;
				var fileName = isEmpty(r.filename)? '' : r.filename;
				var cancelUpload = isEmpty(r.cancel_upload)? '' : r.cancel_upload;
				var done = isEmpty(r.done)? '' : r.done;
				var pct = 0; // percent completed
				var bar = getObject('progressBarFront');
				var barPct = getObject('progressPct');

				// calc rate
				if (rate > 0) rate = parseInt(rate/1024);

				// calc percent completed
				pct = parseInt(100*(currentUploaded/totalSize));

				// cancelled?
				if (cancelUpload > 0 && progressCheckCounter != 0){
					//statusMsg = 'Upload cancelled after ' + r.current + ' bytes.';
					alert('Your upload has been cancelled.');//showMsg('Notice', 'Your upload has been cancelled.');
					dh.nodes.uploadProgressWrapper.hide();
				}else if(done == 1){
					//statusMsg = 'Upload completed.';
					if (tree){
						if(tree.name == 'vault'){
							client.windowFunctions.vault.buildVaultMan(tree);
						}else{
							buildPhotoMan(tree);
						}
						tree.loadFiles();
					}else if(formName == "quickAvatarUploadForm" ){
						dh.nodes.uploadProgressWrapper.hide();
					}else{
						dh.nodes.uploadProgressWrapper.hide();
						client.windows.myForSale.__tab('myForSaleItems');
					}
				}

				// update our display
				bar.style.width = pct + '%';
				barPct.innerHTML = pct + '%';

				// keep checking until its done
				if (done != 1){
					setTimeout(function(){ updateUploadProgress(tree,formName) }, 2000);
				}
			}
			progressCheckCounter++;

			return true;
		},
		function (connectionInstance) {
			//alert('error:'+connectionInstance);
			//for(key in connectionInstance){
				//firebugLog(key +" : " +connectionInstance[key]);
			//}
		}
	);
}



	//---------------------------
	//Music Window
	//---------------------------
	function initProfileMusic(){
		if( !client.windows.profileMusic ){
			client.addWindow( 'profileMusic',
				{
					startingPosition: 	[/*x*/ 0, /*y*/ 0],
					windowStyle:		windowStyle.pane,
					windowPositioning:	windowPositioning.floatLeft,
					windowSizing:		windowSizing.fillHoriz,
					resizable:			false,
					closeButton:		false,
					shadeButton:		true,
					maximizeButton: 	false,
					minimizeButton: 	false,
					showTabs:			false,
					showStatus:			false,
					showIcon:			false,
					showTitle:			true,
					draggable: 			false
				},
				dh.nodes.profile_column1.obj,
				'<div class="fl">History&nbsp;-&nbsp;</div><div class="fl cWhite" style="white-space:nowrap;width:85px;overflow:visible;">Sponsored By</div>'
			);

			dh.createDHObject( "div", "profileMusicCanvas", 'overflowa a o f', dh.nodes.dhWin_profileMusic_canvas.obj, '', none);
			client.windows.profileMusic.setCanvas( dh.nodes.profileMusicCanvas );

			client.windows.profileMusic.onShow = function (){ profileViews() };
			//getObject().innerHTML = '<div class="fl">History&nbps;-</div><div class="fl p cW" style="" onclick="openInvite();">&nbps;Invite&nbps;</div>';
		}
	}

	function profileViews(){

		if(!client.viewHist){
			client.viewHist = {};
			client.viewCount = 0;
		}
		if(!client.viewHist[client.getBrowseUserID()]){
			client.viewHist[client.getBrowseUserID()] =  {};
			client.viewCount++;
			client.viewHist[client.getBrowseUserID()].userName = client.getBrowseUserObject().profile_info.display_name;
			client.viewHist[client.getBrowseUserID()].user_id = client.getBrowseUserID();
			client.viewHist[client.getBrowseUserID()].online = client.getBrowseUserObject().profile_info.online;
			var id = client.viewHist[client.getBrowseUserID()].user_id ;
			var data = client.getBrowseUserObject();


			var wrapper = createObject("div",dhNull,"r fh overflowh");
				wrapper.style.height = "110px";
				wrapper.style.clear = "left";
				//wrapper.style.width = "97px";
			var displayName = (client.viewHist[client.getBrowseUserID()].userName.length < 11) ? client.viewHist[client.getBrowseUserID()].userName : client.viewHist[client.getBrowseUserID()].userName.substring( 0, 8) + '...';

			dh.nodes.profileMusicCanvas.obj.insertBefore(wrapper,dh.nodes.profileMusicCanvas.obj.firstChild);

			wrapper.innerHTML = '<div class="a fh" style="height:18px;top:0px;background:white url(/images/themes/launch/window_white_opaque.jpg) no-repeat scroll 0px -50px;"></div>'+
								'<div class = "r fl fv p" style="background:#BED4F0;"></div>'+
								'<div class = "r fv p">'+
									'<div class="tac gtm" style="line-height:18px;">'+displayName+'</div>'+
									'<div class="tac r bb" style="">'+'Last Login'+'</div>'+
									'<div class="tac r" style="margin-bottom:2px;">'+data.last_login+'</div>'+
									'<div class="tac r bb" style="">'+'Age/Sex'+'</div>'+
									'<div class="tac r" style="margin-bottom:2px;">'+data.user_details.age+'/'+data.user_details.sex+'</div>'+
									'<div class="tac r bb" style="">'+'Location'+'</div>'+
									'<div class="tac r" style="margin-bottom:2px;">'+data.user_details.location+'</div>'+
								'</div>';

			wrapper.onclick = function(){client.browseUser(id)};

			var obj = displayUserAvatar(wrapper.childNodes[1] ,client.viewHist[client.getBrowseUserID()],false,false,false,true).obj.parentNode;
				//obj.className = "avatarNoFloat";
				obj.style.margin = "0px";

			if(client.viewCount <= 1 ){
				dh.nodes.profileMusicCanvas.obj.style.backgroundImage = "url(/images/themes/launch/cbr_hist.png)";
				dh.nodes.profileMusicCanvas.obj.onclick = function(){client.browseUser(6290);}
				hideObject(dh.nodes.profileMusicCanvas.obj.firstChild);
			}else{
				dh.nodes.profileMusicCanvas.obj.onclick = null;
				dh.nodes.profileMusicCanvas.obj.style.backgroundImage = "none";
				showObject(dh.nodes.profileMusicCanvas.obj.childNodes[1]);
			}
		}

	}






function fetchProfileBlogs(){

	if( client.data.profileBlogs ) return true;

	ajax.post( '/api/processors/user',
		{
			type: 'userBlogs',
			i : client.getBrowseUserID()
		},
		function (conn) {
			if(conn && conn.responseObject && conn.responseObject.error){
				switch( conn.responseObject.error ){
					case '6675':
							getObject('blogsCanvas').innerHTML = '<table height="100%" width="100%"><tbody><tr><td height="100%" width="100%" align="center"><img src="/images/perms/windshield.png" width="100%" /></td></tr></tbody></table>';
							return false;
						break;
				}
			}else{
				client.data.profileBlogs = conn.responseObject;
				displayProfileBlogs();
			}
		} ,
		function (connectionInstance) {

		},
		client.windows.windshield
	);

}

function displayProfileBlogs(){

	dh.nodes.blogsCanvas.obj.innerHTML = '';
	var img = ecirkitImagesURL +"tree_expanded.png";
	if (client.data.profileBlogs.length > 0){

		for (var i = 0; i < client.data.profileBlogs.length; i ++){
			var blog = client.data.profileBlogs[i];

			var blogWrapper = createObject('div', 'blogWrapper_' + i, 'blogWrapper', dh.nodes.blogsCanvas.obj);
				var blogTitle = createObject('div', 'blogTitle_' + i, 'blogTitle', blogWrapper, '<img id="blogContentToggle_' + i + '" style="cursor: pointer;" src="'+img+'" />');
				blogTitle.onclick = Function( 'toggleBlogContent(' + i + ');');
				blogTitle.innerHTML += '&nbsp;<a class="gtm" >' + blog.title + '</a>';
				blogTitle.innerHTML += '&nbsp; <em>Created: ' + prepDate(blog.dateCreated) + '</em>';
				if (blog.dateCreated != blog.dateUpdated){
					blogTitle.innerHTML += '&nbsp; <em>Updated: ' + prepDate(blog.dateUpdated) + '</em>';
				}
				var blogContent = createObject('div', 'blogContent_' + i, 'blogContent', blogWrapper, blog.blog);
				if(i > 0)
					blogContent.style.display = 'none';
				img = ecirkitImagesURL + "tree_collapsed.png";
		}

		//dh.nodes.dhWin_windshield.resizeTo(dhNull, 1000);
		//client.windows.windshield.__resize();
	}
}

function toggleBlogContent(index){
	var imgToggle = getObject('blogContentToggle_' + index + '');
	var desc = getObject('blogContent_' + index + '');
	if (desc.style.display == 'none'){
		desc.style.display = 'block';
		imgToggle.src = ecirkitImagesURL + 'tree_expanded.png';
	}else{
		desc.style.display = 'none';
		imgToggle.src = ecirkitImagesURL + 'tree_collapsed.png';
	}
}