function ZPane(options) {
    this.element =$(options.element) || document.createElement('div');
    this.template = options.template;
    
    this.data = options.data || {};
    this.state = options.state || {};
    this.dataMap = options.dataMap;
    
    this.eventHandler = options.eventHandler || [];
    
    Event.observe(this.element, 'click', this.dispatchEvent.bindAsEventListener(this));
}

ZPane.Utils = {
    escape: function(s) {
	return String.interpret(s).escapeHTML().replace(/\"/g, '&quot;');
    }
};

ZPane.prototype = {
    getElement: function() {
	return this.element;
    },
    
    getData: function() {
	return this.data;
    },
    
    setData: function(data) {
	this.data = data;
    },
    
    setDataKey: function(key, value) {
	this.data[key] = value;
    },
    
    getState: function() {
	return this.state;
    },
    
    setState: function(state) {
	this.state = state;
    },
    
    setStateKey: function(key, value) {
	this.state[key] = value;
    },

    update: function() {
	var tmplVars = {};
	for (var k in this.dataMap) {
	    tmplVars[k] = this.dataMap[k](this.data, this.state);
	}
	this.element.innerHTML = this.template.evaluate(tmplVars);
    },
    
    dispatchEvent: function(event) {
	var element = Event.element(event);
	for (var i = 0; i < this.eventHandler.length; i++) {
	    if (this.eventHandler[i].type == event.type && Element.match(element, this.eventHandler[i].selector)) {
		this.eventHandler[i].handler(event, this);
	    }
	}
    }
}
