define('jls/html/HtmlElement', ['jls/lang/Class', 'jls/lang/Logger', 'jls/gui/Element', 'jls/html/DomEvent'], function (Class, Logger, Element, DomEvent) {

var HtmlElement;
HtmlElement = Class.create(Element,
{
    /*initialize : function($super, parameters, parent) {
        $super(parameters, parent);
    },*/
    onCreate : function() {
        this._htmlDispatcher = null;
        this._htmlEventListeners = {};
    	this._htmlElement = this.getAttribute('htmlElement');
    	if (this._htmlElement == null) {
    		this._htmlElement = this.onCreateHtmlElement();
    	}
    },
    onCreateHtmlElement : function() {
        return document.createElement(this.getAttribute('htmlTagName') || 'div');
    },
    getHtmlElement : function() {
    	return this._htmlElement;
    },
    onAddChild : function(child) {
    	if (child instanceof HtmlElement) {
    		this._htmlElement.appendChild(child._htmlElement);
    	}
    },
    onInsertChild : function(index, child) {
        //Logger.getInstance().trace('onInsertChild(' + index + ')');
        if (child instanceof HtmlElement) {
            Logger.getInstance().trace('' + index + '/' + this._htmlElement.childNodes.length);
            this._htmlElement.insertBefore(child._htmlElement, this._htmlElement.childNodes[index]);
        }
    },
    setClass : function(value) {
        this._htmlElement.className = value;
        return this;
    },
    getClass : function() {
        return this._htmlElement.className;
    },
    clean : function() {
        while (this._htmlElement.hasChildNodes()) {
            this._htmlElement.removeChild(this._htmlElement.firstChild);
        }
        return this;
    },
    getTextContent : function() {
        if ((this._htmlElement != null) && (this._htmlElement.firstChild.nodeType == 3)) {
            return this._htmlElement.firstChild.nodeValue;
        }
        return '';
    },
    setTextContent : function(value) {
        this.clean();
    	this._htmlElement.appendChild(document.createTextNode(this.getResourceLabel(value)));
        return this;
    },
    setHtmlContent : function(value) {
        this.clean();
        this._htmlElement.innerHTML = value;
        return this;
    },
    onSetAttribute : function(key, value) {
    	if ((typeof value != 'undefined') && (value != null)) {
        	this._htmlElement.setAttribute(key, value);
    	} else {
            this._htmlElement.removeAttribute(key);
    	}
    },
    onGetAttribute : function(key) {
        return this._htmlElement.getAttribute(key);
    },
    onStyleChange : function(key, oldValue, newValue) {
    	//Logger.getInstance().trace('onStyleChange(' + key + ', ' + oldValue + ', ' + newValue + ')');
        if (this._htmlElement == null) {
            return;
        }
        if (newValue != null) {
            this._htmlElement.style[key] = newValue;
            //this._htmlElement.style.setProperty(key, newValue);
        } else {
            this._htmlElement.style.removeProperty(key);
        }
    },
    _getDispatcher: function() {
        if (this._htmlDispatcher == null) {
            this._htmlDispatcher = (function(e) {
                this.dispatch(new DomEvent(e, this));
            }).bind(this);
        }
        return this._htmlDispatcher;
    },
    observe: function($super, type, handler) {
	    $super(type, handler);
	    if (! (type in this._htmlEventListeners)) {
	        this._htmlEventListeners[type] = this._getDispatcher();
	        HtmlElement.addEventListener(this._htmlElement, type, this._htmlEventListeners[type]);
	    }
    },
    unobserve: function($super, type, handler) {
    	$super(type, handler);
    	if (! this.isObserving(type)) {
    	    HtmlElement.removeEventListener(this._htmlElement, type, this._htmlEventListeners[type]);
    	    delete this._htmlEventListeners[type];
    	}
    },
    onDestroy : function(detach) {
        //jls.logger.trace('onDestroy() ' + this._htmlElement.nodeName);
        if ((! detach) && this._htmlElement) {
            if (this._htmlElement.parentNode) {
                this._htmlElement.parentNode.removeChild(this._htmlElement);
            }
        }
    },
    containsNode : function(node) {
        if (node === this._htmlElement) {
            return true;
        }
        var children = this.getChildren();
        for ( var i = 0; i < children.length; i++) {
            var child = children[i];
            if (child.containsNode(node)) {
                return true;
            }
        }
        return false;
    }
});

Object.extend(HtmlElement,
{
    addEventListener : function(element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else {
            element.attachEvent('on' + type, handler, false);
        }
    },
    removeEventListener : function(element, type, handler) {
        if (element.removeEventListener) {
            element.removeEventListener(type, handler, false);
        } else {
            element.detachEvent('on' + type, handler, false);
        }
    }
});


return HtmlElement;
});
