
Type.registerNamespace('CyberCoders');

CyberCoders.TemplatePopupExtender = function(element) {	
	CyberCoders.TemplatePopupExtender.initializeBase(this, [element]);
	
	this._template = null;
	this._width = null;
	this._contextKey = null;
	this._parameters = null;
	this._popupCssClass = 'popupPanel';
	
	this._pageMethodDelegate = null;
}

CyberCoders.TemplatePopupExtender.prototype = {
	set_template : function(value) {
		this._template = value;
	},
	
	get_template : function() {
		return this._template;
	},
	
	set_width : function(value) {
		this._width = value;
	},
	
	get_width : function() {
		return this._width;
	},
	
	get_parameters : function() {
		return this._parameters;
	},
	
	set_parameters : function(value) {
		this._parameters = value;
	},
	
	get_popupCssClass : function() {
		return this._popupCssClass;
	},
	
	set_popupCssClass : function(value) {
		this._popupCssClass = value;
	},
	
	add_showing : function(handler) {
        this.get_events().addHandler("showing", handler);
    },
    
    remove_showing : function(handler) {
        this.get_events().removeHandler("showing", handler);
    },
    
    raiseShowing : function() {
        var handlers = this.get_events().getHandler("showing");
        if (handlers) {
            handlers(this, Sys.EventArgs.Empty);
        }
    },
    
    add_shown : function(handler) {
        this.get_events().addHandler("shown", handler);
    },
    
    remove_shown : function(handler) {
        this.get_events().removeHandler("shown", handler);
    },
    
    raiseShown : function() {
        var handlers = this.get_events().getHandler("shown");
        if (handlers) {
            handlers(this, Sys.EventArgs.Empty);
        }
    },
    
    add_hiding : function(handler) {
        this.get_events().addHandler("hiding", handler);
    },
    
    remove_hiding : function(handler) {
        this.get_events().removeHandler("hiding", handler);
    },
    
    raiseHiding : function() {
        var handlers = this.get_events().getHandler("hiding");
        if (handlers) {
            handlers(this, Sys.EventArgs.Empty);
        }
    },
    
    add_hidden : function(handler) {
        this.get_events().addHandler("hidden", handler);
    },
    
    remove_hidden : function(handler) {
        this.get_events().removeHandler("hidden", handler);
    },
    
    get_contextKey : function() {
		return this._contextKey;
    },
    
    set_contextKey : function(value) {
		this._contextKey = value;
    },
    
    raiseHidden : function() {

        var handlers = this.get_events().getHandler("hidden");
        if (handlers) {
            handlers(this, Sys.EventArgs.Empty);
        }
    },
    
    showPopup: function() {
		this.raiseShowing();
		
		this._popupElement.innerHTML = '<div class="loading">&#160;</div>';
				
		var old = AjaxControlToolkit.PopupControlBehavior.__VisiblePopup;
        if (old && old._popupBehavior) {
            old.hidePopup();
        }
        
        // reset the location of the popup as it has just resized
		
		
        // reset location to our location
        $common.setLocation(this._popupBehavior.get_element(), { x: this._popupBehavior.get_x(), y: this._popupBehavior.get_y() });

        AjaxControlToolkit.PopupControlBehavior.callBaseMethod(this, 'populate');
        
        // this is done in the base class but we are doing it ourselves for custom positioning
        //this._popupBehavior.set_x(this._getLeftOffset());
        //this._popupBehavior.set_y(this._getTopOffset());
        this._popupBehavior.show();
        this._popupBehavior.set_x(this._getLeftOffset());
		this._popupBehavior.set_y(this._getTopOffset());
        
        // reset location to our location
        $common.setLocation(this._popupBehavior.get_element(), { x: this._popupBehavior.get_x(), y: this._popupBehavior.get_y() });
        
        this._popupVisible = true;
        AjaxControlToolkit.PopupControlBehavior.__VisiblePopup = this;
				
		PageMethods.LoadPopupTemplate(this.get_template(), this._contextKey, this._parameters, this._pageMethodDelegate);		
					
		this.raiseShown();
    },
    hidePopup: function () {
		this.raiseHiding();
		
		CyberCoders.TemplatePopupExtender.callBaseMethod(this, "hidePopup");
		this._popupElement.innerHTML = '';
		
		this.raiseHidden();
    },
		
	initialize : function() {		
		var panel = document.createElement('div');
		panel.className = this._popupCssClass;
		panel.style.display = 'none';
		panel.style.zIndex = 5000;
		
		document.body.appendChild(panel);
		panel.id = this.get_id() + '_PopupPanel';
	
		this._popupControlID = panel.id;
		
		CyberCoders.TemplatePopupExtender.callBaseMethod(this, 'initialize');
		
		if (this._pageMethodDelegate === null) {
			this._pageMethodDelegate = Function.createDelegate(this, this._pageMethodHandler);
		}		
	},
	
	dispose : function() {	
		if (this._popupPanel !== null) {
			try {
				document.body.removeChild(this._popupPanel);
			}
			catch (e) {}
		}
		
		if (this._pageMethodDelegate) {
			delete this._pageMethodDelegate;
		}
		
		CyberCoders.TemplatePopupExtender.callBaseMethod(this, 'dispose');
	},
	
	_pageMethodHandler : function(e) {	
		var div = document.createElement('div');
		
		// HACK: Used to 'shrink' div to fit the size of it's contents
		if (div.style.cssFloat)
			div.style.cssFloat = "left";
		else
			div.style.styleFloat = "left";
			
		this._popupElement.innerHTML = '';

		if (Sys.Browser.agent == Sys.Browser.InternetExplorer) {
			this._popupElement.appendChild(div);				
			div.innerHTML = e;		
		}	
		
		// HACK: Safari doesn't support dynamic script tags very well
		// so any top-level script tags will get removed and new script objects
		// are added in their place
		else if (Sys.Browser.agent == Sys.Browser.Safari) {
			div.innerHTML = e;
			this._popupElement.appendChild(div);
			
			var oldChildren = new Array();
			var newChildren = new Array();
			
			for (var i = 0; i < div.childNodes.length; i++) {
				if (div.childNodes[i].tagName == 'SCRIPT') {
					oldChildren.push(div.childNodes[i]);
					
					var s = document.createElement('script');
					s.type = 'text/javascript';
					s.innerHTML = div.childNodes[i].innerHTML;
					
					newChildren.push(s);
				}
			}
			
			for (var i = 0; i < oldChildren.length; i++)
				div.removeChild(oldChildren[i]);
			for (var i = 0; i< newChildren.length; i++)
				div.appendChild(newChildren[i]);
		}
		
		else {
			div.innerHTML = e;
			this._popupElement.appendChild(div);
		}
		
		// WORKAROUND: get the size of the largest child and use that as the
		// width of the parent since it does not get resized in most browsers
		var size = Sys.UI.DomElement.getBounds(div);
		
		var maxWidth = 0;
		for (var i = 0; i < div.childNodes.length; i++) {
			if (div.childNodes[i].nodeType == 1) {
				var s = $common.getSize(div.childNodes[i]);
				maxWidth = Math.max(maxWidth, s.width);
			}
		}
		$common.setContentSize(this._popupElement, { width: this._width == null ? maxWidth : this._width, height: size.height});
		
		// use auto height
		this._popupElement.style.height = "auto";
		
		// reset the location of the popup as it has just resized
		this._popupBehavior.set_x(this._getLeftOffset());
		this._popupBehavior.set_y(this._getTopOffset());
		
        // reset location to our location
        $common.setLocation(this._popupBehavior.get_element(), { x: this._popupBehavior.get_x(), y: this._popupBehavior.get_y() });
        
        if (typeof(onPopupLoaded) === 'function')
			onPopupLoaded();
	},
	
	
	_getTopOffset: function() {
		var bounds = Sys.UI.DomElement.getBounds(this._popupElement);
		var targetBounds = Sys.UI.DomElement.getBounds(this.get_element());
		var p = this.get_Position();
		
		var top = 0;
		var outside = 0;
		
		if (p & CyberCoders.PopupVerticalPosition.Top) {	
			if (p & 0x20) {
				outside = -bounds.height;
			}
			
			top = targetBounds.y;
		}
		
		else if (p & CyberCoders.PopupVerticalPosition.Bottom) {
			if (p & 0x20) {
				outside = targetBounds.height;
			}
			
			top = targetBounds.y;
			
		}
		
		// center
		else {
			outside = 0;
			top = targetBounds.y - Math.round(bounds.height / 2) + Math.round(targetBounds.height / 2);
		}
				
		
		return top + this._offsetY + outside;
	},
	
	_getLeftOffset: function() {
		var bounds = Sys.UI.DomElement.getBounds(this._popupElement);
		var targetBounds = Sys.UI.DomElement.getBounds(this.get_element());
		var p = this.get_Position();
		
		var left = 0;
		var addWidth = 0;
		
		if (p & CyberCoders.PopupHorizontalPosition.Left) {
			left = targetBounds.x;
			addWidth = (p & 0x10)? -1 : 0;
		}
		
		else if (p & CyberCoders.PopupHorizontalPosition.Right) {
			left = targetBounds.x + targetBounds.width;			
		}
		
		// center
		else {
			addWidth = 0;
			left = targetBounds.x - Math.round(bounds.width / 2) + Math.round(targetBounds.width / 2);
		}			
		
		return left + this._offsetX + (bounds.width * addWidth);
	}
}

CyberCoders.TemplatePopupExtender.registerClass('CyberCoders.TemplatePopupExtender', AjaxControlToolkit.PopupControlBehavior);

CyberCoders.PopupHorizontalPosition = function() {
	throw Error.invalidOperation();
}
CyberCoders.PopupHorizontalPosition.prototype = {
	Center : 0,
	Left :  0x01,
	Right : 0x02,
	LeftOutside : 0x10 | 0x01,
	RightOutside : 0x10 | 0x02
}

CyberCoders.PopupHorizontalPosition.registerEnum("CyberCoders.PopupHorizontalPosition", false);

CyberCoders.PopupVerticalPosition = function() {
	throw Error.invalidOperation();
}
CyberCoders.PopupVerticalPosition.prototype = {
	Center : 0,
	Top :  0x04,
	Bottom : 0x08,
	TopOutside : 0x20 | 0x04,
	BottomOutside : 0x20 | 0x08
}

CyberCoders.PopupVerticalPosition.registerEnum("CyberCoders.PopupVerticalPosition", false);

if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
