/**
 * Widget that creates a floating 'panel'
 */
(function () {
	
	/**
	 * @param id
	 *            Id used for the panel that is created
	 * @param url
	 *            Address of the content for the panel so it can be loaded via
	 *            an ajax request
	 * @param options
	 *            Configuration object to control various features of the panel
	 *            -showOnLoad Default = false - If set to true, the panel will
	 *            be shown on page load -opener Default = null -Either an ID or
	 *            an object with the following attributes: -id ID of element to
	 *            attach a click listener to that will cause the panel to be
	 *            shown when it is clicked -test Reference to a function to call
	 *            that returns a boolean that determines whether to show the
	 *            panel or not -height Default = 250 - Sets the height of the
	 *            panel -width Default = 500 - Sets the width of the panel
	 *            -close Default = false - Whether a "close" icon should be
	 *            displayed in the header. -draggable Default = true - Whether
	 *            to allow the user to drag the Panel using its header.
	 *            -underlay Default = 'shadow' - Specifies the type of underlay
	 *            to display under the Panel. Other options include "none", and
	 *            "matte", which renders a small white matte under the Panel.
	 *            -modal Default = false - Specifies whether the document should
	 *            be shielded with a partially transparent mask to require the
	 *            user to close the Panel before being able to activate any
	 *            elements in the document. -effect Default = null - Sets the
	 *            ContainerEffect (one or many) that should be used when showing
	 *            and hiding the Panel. -context Default = null - Allows the
	 *            Overlay to be aligned relative to a context element. The
	 *            property expects an array value with the format:
	 *            [contextElementOrId, overlayCorner, contextElementCorner],
	 *            where "contextElementOrId" is the context element or the id of
	 *            the context element. See YUI Doc for details on properties of
	 *            array
	 * 
	 */
	nmdgf.widgets.Panel = function(id, url, options) {
	    options = options || {};
		this.id = id;
		this.url = url;
		this.options = options;
		nmdgf.registerWidget(this);
	};		
	
	nmdgf.widgets.Panel.prototype = {
		
		/**
		 * ID of panel
		 */
		id : null,
		
		/**
		 * Configuration options object
		 */
		options : null,
		
		/**
		 * Address where body content is to be loaded from
		 */
		url : null,
		
		/**
		 * Instance of YAHOO.widget.Panel
		 */
		panel : null,
		
		/**
		 * Default value for a submit button
		 */
		defaultSubmitButtonValue : 'Ok',
		
		/**
		 * Default value for a button that closes the panel
		 */
		defaultCloserButtonValue : 'Cancel',
		
		/**
		 * Runs on page load - shows panel if configured to, attaches opener
		 * listener if set
		 */
		initialize : function() {
		    if(this.options.showOnLoad === true) {
		        this.show();
		    }
		    if(this.options.opener !== undefined) {
		    	if(typeof this.options.opener  === 'string') {
		    		nmdgf.addListener(this.options.opener, 'click', this.openerClicked, this);
		    	}else {
		    		nmdgf.addListener(this.options.opener.id, 'click', this.openerClicked, this);
		    	}
		    }
		},
		
		/**
		 * Handles a click event for an opener - shows the panel
		 */
		openerClicked : function(e) {
			var show = true;
			if(this.options.opener.test !== undefined) {
				var elements = this.options.opener.test.split('.');
				elements.pop();
				var scope = eval(elements.join('.'));
				show = eval(this.options.opener.test).call(scope, e);
			}
			if(show === true) {
			    nmdgf.stopEvent(e);
			    this.show();
			}
		},
		
		/**
		 * Shows the panel - Lazily creates the panel if not already created
		 */
		show : function() {
			nmdgf.widgets.LoadingPanel.show();
			if(this.panel === null) {
				this.createPanel();
			}
			this.setHeightWidth();
			this.loadContent();
		},
		
		/**
		 * Hides the panel
		 */
		hide : function() {
			this.panel.hide();
		},
		
		/**
		 * Loads the body content from the url via an ajax request
		 */
		loadContent : function() {
			nmdgf.ajax('GET', this.url, {
				success: function(r) {
					nmdgf.widgets.LoadingPanel.hide();
					this.panel.setBody(r.responseText);
					this.panel.show();
				}, scope: this
			});
		},
		
		/**
		 * Sets the height and width of the panel
		 */
		setHeightWidth : function() {
			var height = this.options.height || '250';
			var width = this.options.width || '500';
			this.panel.cfg.setProperty('height', height+'px');
			this.panel.cfg.setProperty('width', width+'px');
			this.panel.center();
		},
		
		/**
		 * Creates the panel object and renders it to the document body
		 */
		createPanel : function() {
			this.panel = new YAHOO.widget.Panel(this.id, {
				fixedcenter : true,
				constraintoviewport : true,
				underlay : this.options.underlay || 'shadow',
				close : (this.options.close === false ? false : true),
				visible : false,
				draggable : (this.options.draggable === false ? false : true),
				modal: (this.options.modal === true ? true : false),
				effect : (this.options.effect !== undefined ? this.options.effect : null),
				context : this.options.context !== undefined ? this.options.context : null
			}); 
			this.panel.setHeader(this.options.title || '&nbsp;');
			this.panel.setBody('&nbsp;');
			this.panel.setFooter(this.buildFooter());
			this.panel.render(document.body);
		},
		
		/**
		 * Generate Footer HTML to add buttons if set in options Adds even
		 * listeners to handle the button clicks
		 */
		buildFooter : function() {
		    var footer = '';
		    var buttons = this.options.buttons;
		    if(buttons !== undefined) {
		        if(buttons.submit !== undefined) {
		            var submitId = this.id +'_button_submit';
		            footer += '<input type="submit" value="'+ ( buttons.submit.value || this.defaultSubmitButtonValue ) +'" id="'+ submitId +'" />';
		            nmdgf.addListener(submitId, 'click', function() {
		                // TODO: manually calling submit() on a form does not
						// fire its submit event, have to manually fire
						// DateField function that is listening to event. Need
						// to find a generic way of handling this
		                nmdgf.widgets.DateField.clearEmptyDates();
		                nmdgf.byId(buttons.submit.form).submit();
		            });
		        }
		        if(buttons.closer !== undefined) {
		            var closerId = this.id +'_button_cancel';
		            footer += '<input type="submit" value="'+ ( buttons.closer.value || this.defaultCloserButtonValue ) +'" id="'+ closerId +'" />';
		            var that = this;
		            nmdgf.addListener(closerId, 'click', function() {
		                that.hide();
		            });
		        }
		    }
		    return footer;
		}
	};

})();
