KWindow = {
	id : window.location.href+"_"+(new Date().getTime())
	, open : function(sUrl, options) {
		var originalOptions = Object.extend({},options);
		var sWinName = "kWindow"+(new Date().getTime());
		var iHeight = options.height;
		var iWidth = options.width;
		var sActionScript = options.actionScript || null;
		var winOpener = options._opener || window;
		options._opener = null;
		this._prepareCallbackFunctions(sWinName,options,winOpener);
		var bModal = options.modal;
		options.modal = options.modal ? "true" : "false";
		options.name = null;
		options.height = null;
		options.width = null;
		options.actionScript = null;
		var sParams = this._encodeParams(options);
		if(sUrl.indexOf("?") < 0) {
			sUrl += "?";
		} else {
			sUrl += "&";
		}
		var win = new Window({
			id : sWinName
			, title: decodeURIComponent(options.title || "")
			, url: sUrl+sParams
			, width: iWidth
			, height: iHeight
			, minimizable: options.minimizable || false
			, maximizable: options.maximizable || false
			, showEffectOptions: {duration: 0.15}
			, hideEffectOptions: {duration: 0.15}
			, parent: window.top.document.body
			, zIndex: options.zIndex || 100000
			, destroyOnClose: true
		});
		win._opener = winOpener;
		win.showCenter(bModal);
		var eWinContentFrame = Element.getElementsBySelector(win.element,"iframe#"+win.getId()+"_content")[0];
		Event.observe(eWinContentFrame,"load",this._newContentLoadCallback(originalOptions,win));
		eWinContentFrame._kWindow = win;
	}
	, dialog : function(options) {
		var sUrl = options.dialog || KBase.toFullUrl("/popup/KDialog.html");
		this.open(sUrl,options);
	}
	, confirm : function(options) {
		var sUrl = options.kWindowUrl || KBase.toFullUrl("/popup/KConfirm.html");
		if(typeof options.modal == "undefined") {
			options.modal = true;
		}
		options.onComplete = options.onComplete || options.actionScript;
		this.open(sUrl,options);
	}	
	, getOpener : function() {
		var pWin = this.getCurrentPopupWindow();
		//PHD 8/6/2007 - First try to get the opener reference on the Window instance
		if(pWin && pWin._opener) return pWin._opener;
		//PHD 8/6/2007 - Just punt and say the top window was the opener
		if(window == window.top) {
			if(window.opener) {
				return window.opener;
			}
		}
		return window.top;
	}
	, reloadOpener : function(localContext) {
		var winOpener = this.getOpener();
                if (localContext != null) {
                   var idx = winOpener.location.href.indexOf("#");
                   if (idx == -1) {
	             winOpener.location.href = winOpener.location.href+localContext;
                   }
                   else {
                     winOpener.location.href = winOpener.location.href.substring(0,idx)+localContext;
                   }
                }
                else {
		   winOpener.location.href = winOpener.location.href;
                }
	}
	, close : function(sWinId) {
		if(typeof Windows != 'undefined') {
			if(sWinId) {
				Windows.close(sWinId);				
			} else {
				Windows.closeAll();
			}
		} else {
			var kWindow = this.getCurrentPopupWindow();
			if(kWindow) {
				kWindow.close();
			}
		}
	}
	, closeAndReload : function() {
		this.close();
		this.reloadOpener();
	}
	, callOnComplete : function() {
		var pWin = this.getCurrentPopupWindow();
		var oOriginalWin = this.getOpener();
		if(pWin && oOriginalWin) {
			var arrCallbackArgs = [pWin.getId(),"onComplete"];
			for(var i=0; i<arguments.length; i++) {
				arrCallbackArgs.push(arguments[i]);
			}
			var origKWindow = oOriginalWin.KWindow;
			origKWindow.doCallback.apply(origKWindow,arrCallbackArgs);
		}
	}
	, doCallback : function(sWinName, sFunctionKey) {
		var fCallback = this._getCallbackRegistry().getCallbackFunction(sWinName,sFunctionKey,true);
		if(fCallback) {
			var arrFuncArgs = [];
			if(arguments.length > 2) {
				for(var i=2; i<arguments.length; i++) {
					arrFuncArgs.push(arguments[i]);
				}
			}
			return fCallback.apply({},arrFuncArgs);
		}
	}
	, getCurrentPopupWindow : function() {
			//PHD 7/20/2007 - Since the location of the _kWindow attribute is not 
			//always the same relative to the content of the popup which is calling 
			//this function, try several locations to find the right one.
			var arrPossKWindows = [
				function() { return window.parent.frameElement._kWindow} //Dialog with frameset
				, function() { return window.frameElement._kWindow } //Popup in iframe
				, function() { return window.document._kWindow } //Last resort
			];
			for(var i=0; i<arrPossKWindows.length; i++) {
				try {
					var oWin = arrPossKWindows[i]();
					if(typeof oWin != "undefined") {
						return oWin;
					}
				} catch(ex) {}
			}	
			return null;
	}
	, _newContentLoadCallback : function(opts,win) {
		return function() {
			var eIFrame = Element.getElementsBySelector(win.element,"iframe#"+win.getId()+"_content")[0];
			if(eIFrame) {
				eIFrame.contentWindow._kWindow = win;
				//PHD 7/20/2007 - FF, IE and Safari have slightly different ways of getting the document
				var eDocument = eIFrame.contentDocument || eIFrame.contentWindow.document;
				if(eDocument) {
					eDocument._kWindow = win;
					if(!opts.title) {
						win.setTitle(eDocument.title); 
					}					
				}
			}	
		}
	}
	, _encodeParams : function(oParams, arrNames) {
		var arrParams = new Array();
		if(arrNames) {
			for(var i=0; i<arrNames.length; i++) {
				var sName = arrNames[i];
				var sValue = oParams[sValue];
				if(sValue || (typeof sValue == 'string')) {
					arrParams.push(this._encodeParam(sName,sValue));
				}
			}
		} else {
			for(var sName in oParams) {
				var sValue = oParams[sName];
				if(sValue || (typeof sValue == 'string')) {
					arrParams.push(this._encodeParam(sName,sValue));
				}
			}
		}
		return arrParams.join("&");
	}
	, _encodeParam : function(sName, sValue) {
		return sName+"="+sValue;
	}
	, _prepareCallbackFunctions : function(sWinName,options,bindWindow) {
		if(!options.onComplete) return;
		var fOnComplete = null;
		if(typeof options.onComplete != "string") {
			fOnComplete = options.onComplete;				
		} else {
			var sOnCompleteCode = options.onComplete;
			fOnComplete = function() {
				//PHD 10/4/2007 - Ensure code is run in requested window
				bindWindow.eval(sOnCompleteCode);
			}
		}
		this._getCallbackRegistry().registerCallbackFunction(sWinName,"onComplete",fOnComplete);
		options.onComplete = "KWindow.doCallback('"+sWinName+"','onComplete');";
	}
	, _getCallbackRegistry : function() {
		return window.top.KWindowCallbackRegistry;
	}
}
if(typeof Window != "undefined") {
	//PHD 7/21/2007 - Ensures that multiple modal windows can be stacked on top of each other
	Window.keepMultiModalWindow = true;
}
if(window.top != window && window.top.KWindow) {  
     //PHD 7/21/2007 - Routes open requests to top level KWindow so that dialogs   
     //opened from within dialogs (which exist in iframes) are able to function correctly  
     KWindow._window = window;  
     KWindow._open = KWindow.open;  
     KWindow.open = function(sUrl,options){  
          options._opener = this._window;  
          if(options.openInCurrentWindow) {  
               KWindow._open(sUrl,options);  
          } else {  
               window.top.KWindow.open(sUrl,options);  
          }  
     };  
}
//if(window.top != window && window.top.KWindow) {
//	//PHD 7/21/2007 - Routes open requests to top level KWindow so that dialogs 
//	//opened from within dialogs (which exist in iframes) are able to function correctly
//	KWindow._window = window;
//	KWindow.open = function(sUrl,options){
//		options._opener = this._window;
//		window.top.KWindow.open(sUrl,options);
//	};
//}
if(typeof window.top.KWindowCallbackRegistry == "undefined") {
	window.top.KWindowCallbackRegistry = {
		registerCallbackFunction : function(sWinName, sCallbackName, fCallback) {
			var callbackMap = this._getCallbackFunctionsByKWindow()[sWinName];
			if(!callbackMap) {
				callbackMap = {};
				this._getCallbackFunctionsByKWindow()[sWinName] = callbackMap;
			}
			callbackMap[sCallbackName] = fCallback;
		}
		, getCallbackFunction : function(sWinName, sCallbackName) {
			var callbackMap = this._getCallbackFunctionsByKWindow()[sWinName];
			if(!callbackMap) return null;
			return callbackMap[sCallbackName];
		}
		, _getCallbackFunctionsByKWindow : function() {
			if(!this.callbackFunctionsByKWindow) {
				this.callbackFunctionsByKWindow = {};
			}
			return this.callbackFunctionsByKWindow;
		}
	}
}

