$.ui.component.subclass('ui.panel', {

	_init: function() {
		var self = this, 
			options = this.options, 
			panel = this.panel = self.element, 
			panelHeader = this.panelHeader = panel.find(options.headerSelector), 
			panelBody = this.panelBody = panel.find(options.bodySelector), 
			panelFooter = this.panelFooter = panel.find(options.footerSelector),
			panelButtons = this.panelButtons = panel.find(options.buttonsSelector);
		this.create();
	}, 
	hide: function(event) {this.panel.hide();}, 
	show: function(event) {this.panel.show();}, 
	create: function(event) {
		this.createHeader();
		this.createBody();
		this.createFooter();
		this.createButtons();
	}, 
	destroy: function(event) {
		this.destroyHeader();
		this.destroyBody();
		this.destroyFooter();
		this.destroyButtons();
	}, 
	// Buttons
	createButtons: function() {}, 
	destroyButtons: function() {}, 
	// Header
	createHeader: function() {}, 
	destroyHeader: function() {}, 
	// Body
	recreateBody: function(content) {
		this.destroyBody();
		this.panelBody.html(content);
		this.createBody();
	}, 
	createBody: function() {}, 
	destroyBody: function() {}, 
	// Footer
	createFooter: function() {}, 
	destroyFooter: function() {}, 
	hasPageOptions: function() {
		return (this.options.page && this.options.page.widget && this.options.page.object) ? true : false;
	}, 
	getPageOptions: function() {return {page: this.options.page};}, 
	callPage: function(method, params) {
		var options = this.getPageOptions();
		if (options && options.page && options.page.widget && options.page.object) 
			$.plugin(options.page.object, options.page.widget, method, params);
	}, 
	hasParentOptions: function() {
		return (this.options.parent && this.options.parent.widget && this.options.parent.object) ? true : false;
	}, 
	getParentOptions: function() {return this.options.parent;}, 
	callParent: function(method, params) {
		if (this.hasParentOptions()) {
			$.plugin(this.getParentOptions().object, this.getParentOptions().widget, method, params);
		}
	}, 
	getURL: function() {return this.panel.attr('url');}, 
	cmd: function(query, handler, container) {
		var url = this.getURL();
		if (query) url += '/' + query;
		var container_ = (container) ? container : this.panel;
		$.request({url: url, scope: this, func: handler, container: container_, arguments: {query: query}});
	}, 
	loadBodyHandler: function(responce, arguments) {
		if (responce.html) {
			this.recreateBody(responce.html.body);
			this.show();
		}
	}, 
	loadBody: function(query) {this.cmd(query, this.loadBodyHandler);}
});
$.ui.panel.defaults.extend({
	headerSelector: ' > .panel-header', 
	bodySelector: ' > .panel-body', 
	footerSelector: ' > .panel-footer', 
	buttonsSelector: ' > .panel-buttons'
});

