
// Usage:
// x = new PopupWindow(1000, 500);
// x.NavigateURL("UserRegistration.aspx", "popup=true");
// new Draggable(x.id, x.id, x.dragOptions);
// x.Show(true);

UILocker = {
	locked: false,
	element: null,
	popup: null,
	
	Lock: function UILocker_Lock(popup) {
		var _this = this;
		if (popup) {
			this.popup = popup;
		}
		
		if (!this.locked) {
			if (!this.element) {
				this.element = DOMObjectFactory.CreateDOMObject("div", false, document.body);
				this.element.applyClass("scrLogin"); // UILocker
			}	
			
			this.element.setStyleAttribute("display", "block")
			this.locked  = true;
		}
	},
	
	Unlock: function UILocker_Unlock(popup) {
		if (this.locked) {
			this.element.setStyleAttribute("display", "none")
			this.locked = false;
		}	
	}
};


DeclareClass("PopupWindow", null,
{
	constructor: function PopupWindow_Constructor(title, width, height, left, top, scrollbars, closable, hideTitleBox) {

		this.title = title;
		this.defaultWidth  = 600;
		this.defaultHeight = 500;
		this.hideTitleBox = !!hideTitleBox;
		this.contentOffset = this.hideTitleBox ? 0 : 35; // content frame top offset in pixels

		closable = !hideTitleBox && (typeof(closable) == "undefined" ? true : closable);
		
		// default parameters processing
		width = width || this.defaultWidth;
		height = height || this.defaultHeight;
				
		left = left || ((document.body.clientWidth/2) - (parseInt(width)/2));
		top  = top  || Math.max(0, document.body.clientHeight/2 - parseInt(height)/2);		
		
		// init main window
		this.initWindow(width, height, left, top);
		
		// init inner <iframe /> 
		this.initFrame(scrollbars);
		
		// create title 
		if (!hideTitleBox) {
			this.createTitle(this.title);
		}

		// close button initialization		
		if (closable) {
			this.initCloseButton();
		}	
		
		// dragging support
		this.initDragSupport();
	},
	
	NavigateURL: function PopupWindow_NavigateToURL(URL, params) {
		this.navigate(url_AddParameters(URL, params));
	},
	
	NavigatePID: function PopupWindow_NavigateToURL(PID, params) {
		this.navigate(url_AddParameters(nav_buildPopupUrl(PID), params));
	},
	
	navigate:  function PopupWindow_navigate(URL) {
		this.frame.setAttribute("src", URL);
	},
	
	initWindow: function  PopupWindow_initWindow(width, height, left, top) {
		
		var _this = this;		
		// window object
		this.element = DOMObjectFactory.CreateDOMObject("div", false, document.body);
		
		// assign unique ID
		this.id = "popup_" + Number(new Date());
		this.element.setAttribute("id", this.id);		
		this.handlerId = this.id + "_handler";
		this.shieldId = this.id + "_shield";
		
		this.element.setStyleAttribute("width", width, "px");
		this.element.setStyleAttribute("height", height, "px");
		this.element.setStyleAttribute("left", left, "px");
		this.element.setStyleAttribute("top", top, "px");		
		this.element.applyClass("popupWnd");
	},
	
	createTitle: function PopupWindow_createTitle(text) {
		var title = DOMObjectFactory.CreateDOMObject("div", false, this.element.Obj());
		title.setInnerText(text);
		title.applyClass("popupTitle");		
	},	
	
	initCloseButton: function PopupWindow_initCloseButton() {
	
		var _this = this;
		var closeBtn = DOMObjectFactory.CreateDOMObject("div", false, this.element.Obj());		

		this.closeHovered = false; 
		dom_attachEventForObject(closeBtn.Obj(), "click", function() { _this.Hide(true); } ); 
		dom_attachEventForObject(closeBtn.Obj(), "mouseover", function() { _this.closeHovered = true; } ); 
		dom_attachEventForObject(closeBtn.Obj(), "mouseout", function() { _this.closeHovered = false; } ); 
		
		closeBtn.applyClass("closeBtn");
	},
	
	initFrame: function PopupWindow_initFrame(scrollbars) {
		// create inner <iframe /> element
		this.element.setInnerHTML("<iframe class=\"frame\" scrolling=\"~0\" frameborder=\"no\" />".format(scrollbars ? "yes" : "no"));	
	
		this.frame = new dom_DOMObject(this.element.Obj().getElementsByTagName("IFRAME")[0]);		
		this.frame.setStyleAttribute("top", this.contentOffset + 2, "px");
		this.frame.setStyleAttribute("height", this.element.Obj().offsetHeight - this.contentOffset - 2, "px");
		this.frame.setStyleAttribute("width", this.element.Obj().offsetWidth - 2, "px");
		this.frame.Obj().onload = this.frame.Obj().contentWindow.onload = this.CreateCallback(this.onLoad);				
	},	
	
	onLoad: function PopupWindow_onLoad() {
		var _this = this;
		if (this.frame && this.frame.Obj()) {
			var contentWindow = this.frame.Obj().contentWindow;
			contentWindow.opener = window;
			contentWindow.close = function() { _this.Hide(true); };
		}
	},
	
	Show: function PopupWindow_Show(modal) {
		if (this.element) {
			this.modal = !!modal;
			//TODO: multiple locking requests processing - locking stack?
			if (this.modal) {
				UILocker.Lock(this);
			}
			this.element.setStyleAttribute("visibility", "visible")
		}
	},	
	
	Hide: function PopupWindow_Hide(destroy) {
		if (this.element) {			
			if (destroy) {
				//TO DO: VK memory leak problem
				var iframes = this.element.Obj().getElementsByTagName("IFRAME");
				if (iframes.length > 0) {	
					var iframe = iframes[0];
					evnt_UnRegisterPopup(iframe.contentWindow);
					iframe.src = "";
					iframe.onload = Function.Empty;
					var contentWindow = iframe.contentWindow;
					if (contentWindow  && contentWindow.document && 
						contentWindow.document.readyState == 'complete' && contentWindow.DOMGarbageCollector) {
						contentWindow.DOMGarbageCollector.ReleaseAllObjects(contentWindow.DOMGarbageCollector);
					}
				}
				dom_RemoveNode(this.element.Obj(), true);
				this.element = null;
			} else {
				this.element.setStyleAttribute("visibility", "hidden");
			}
			if (this.modal) {
				UILocker.Unlock();
			}
		}
	},
	
	initDragSupport: function PopupWindow_initDragSupport() {
		var _this = this;
		// screen <iframe /> behind <div /> element not to interfere while dragging
		var shield = DOMObjectFactory.CreateDOMObject("div", false, this.element.Obj());
		shield.setAttribute("id", this.shieldId);	
		shield.applyClass("popupShield");
		
		this.onDragStart.handler = this.CreateCallback(this.onDragStart);
		this.onDragEnd.handler = this.CreateCallback(this.onDragEnd);
		
		this.dragOptions = {
			onDragStart: _this.onDragStart.handler,
			onDragEnd: _this.onDragEnd.handler			
		}		
	},		
	
	onDragStart: function PopupWindow_onDragStart() {
		// disable window dragging in case close button is hovered over
		if (!this.closeHovered) {
			new dom_DOMObject(this.shieldId).setStyleAttribute("display", "block");
		}
		return !this.closeHovered;
	},
	
	onDragEnd: function PopupWindow_onDragEnd() {
		new dom_DOMObject(this.shieldId).setStyleAttribute("display", "none");
	}
});

DeclareClass("Draggable", null,
{
	constructor: function Draggable_Constructor(targetId, handlerId, options) {
		this.targetId = targetId;
		this.handlerId = handlerId;		
		this.options = options;
		
		// prevent default behaviour for IE
		$(handlerId).ondragstart = function() { return false; };

		this.onDragStart.handler = this.CreateCallback(this.onDragStart);
		dom_attachEventForObject($(this.handlerId), "mousedown", this.onDragStart.handler);
	}, 
	
   onDragStart: function Draggable_onDragStart(e) {
		var dragEnabled = true;
		if (this.options && this.options.onDragStart && typeof(this.options.onDragStart) == "function") {
			dragEnabled = this.options.onDragStart();
		}	
		
		if (dragEnabled) {
			this.x = e.clientX; 
			this.y = e.clientY; 
			this.offsetX = e.clientX - this.x;
			this.offsetY = e.clientY - this.y;
			new dom_DOMObject(this.targetId).applyClass("draggable");
			
			if (!this.onDragEnd.handler) {
				this.onDragEnd.handler = this.CreateCallback(this.onDragEnd);
			}
			
			if (!this.onDrag.handler) {
				this.onDrag.handler = this.CreateCallback(this.onDrag);
			}
			
			dom_attachEventForObject(document.body, "mousemove", this.onDrag.handler, null, true);
			dom_attachEventForObject(document.body, "mouseup", this.onDragEnd.handler, null, true);            
		
			this.isDragInProgress = true;
        }
    },
    
    onDrag: function Draggable_onDrag(e) {
        var el = new dom_DOMObject(this.targetId);
        
        el.setStyleAttribute("left", parseInt(this.getStyle(el, "left"))  + (e.clientX - this.x), "px");
        el.setStyleAttribute("top", parseInt(this.getStyle(el, "top")) + (e.clientY - this.y), "px");
        this.x = e.clientX;
        this.y = e.clientY;
    },
    
    onDragEnd: function Draggable_onDragEnd(e) {
        dom_detachEventForObject(document.body, "mousemove", this.onDrag.handler, null, true);
        dom_detachEventForObject(document.body, "mouseup", this.onDragEnd.handler, null, true);
        new dom_DOMObject(this.targetId).removeClass("draggable");
        
		if (this.options && this.options.onDragEnd && typeof(this.options.onDragEnd) == "function") {
				this.options.onDragEnd();
		}        
        this.isDragInProgress = false;
    },
    
    getStyle: function Draggable_getStyle(id, property) {
        var el = $(this.targetId);
        var value = el.currentStyle ? el.currentStyle[property] :
                    window.getComputedStyle(el, null).getPropertyValue(property);
                    
        return value == "auto" ? null : value;       
    }		
});
