/**
 * Create namespace
 */
nl.xd.XD.namespace( 'nl.xd.dom' ) ;

/**
 * DOM Class
 */
nl.xd.dom.DOM = {
	/**
	 * @param HTMLElement
	 * @return integer
	 */
	width: function( element ) {
		return element.offsetWidth ;
	} ,
	
	/**
	 * @param HTMLElement
	 * @return integer
	 */
	height: function( element ) {
		return element.offsetHeight ;
	} ,
	
	/**
	 * @param string
	 * @return HTMLElement
	 */
	get: function( id ) {
		return document.getElementById( id ) ;
	} ,
	
	/**
	 * @param HTMLElement
	 * @param string
	 * @param string
	 * @return HTMLElement
	 */
	getParent: function( element , tagName , className ) {
		if ( tagName == null ) {
			return element.parentNode ;
		} else {
			while ( element.tagName != null ) {
				if ( ( element.tagName.toLowerCase() == tagName ) && ( className == null || this.hasClass( element , className ) ) ) {
					return element ;
				} ;
				
				element = element.parentNode ;
			} ;
			
			return element ;
		} ;
	} ,
	
	/**
	 * @param HTMLElement
	 * @param string
	 * @param string
	 * @return HTMLElement
	 */
	hasParent: function( element , tagName , className ) {
		while ( element.tagName != null ) {
			if ( ( element.tagName.toLowerCase() == tagName ) && ( this.hasClass( element , className ) ) ) {
				return true ;
			} ;
			element = element.parentNode ;
		} ;

		return false ;
	} ,
	
	/**
	 * @param string
	 * @param HTMLElement
	 * @return array
	 */
	getByTagName: function( tag , root ) {
		return root.getElementsByTagName( tag ) ;
	} ,
	
	/**
	 * @param string
	 * @param string
	 * @param HTMLElement
	 * @return array
	 */
	getByClassName: function( className , tag , root ) {
		var childs   = root.getElementsByTagName( tag ) ;
		var elements = new Array() ;
		
		for ( var i = 0; i < childs.length; i++ ) {
			if ( this.hasClass( childs[ i ] , className ) ) {
				elements.push( childs[ i ] ) ;
			} ;
		} ;
		
		return elements ;
	} ,
	
	/**
	 * @param HTMLElement
	 * @param string
	 * @return boolean
	 */
	hasClass: function( element , className ) {
		var re = new RegExp( '(?:^|\\s+)' + className + '(?:\\s+|$)' ) ;
		
		return re.test( element[ 'className' ] ) ;
	} ,
	
	/**
	 * @param HTMLElement
	 * @param string
	 * @return void
	 */
	addClass: function( element , className ) {
		if ( this.hasClass( element , className ) ) {
			return ;
		} ;
		
		element[ 'className' ] = [ element[ 'className' ] , className ].join( ' ' ) ;
	} ,
	
	/**
	 * @param HTMLElement
	 * @param string
	 * @return void
	 */
	removeClass: function( element , className ) {
		if ( ! this.hasClass( element , className ) ) {
			return ;
		} ;
		
		var re = new RegExp( '(?:^|\\s+)' + className + '(?:\\s+|$)' , 'g' ) ;
		var c  = element[ 'className' ] ;
		
		element[ 'className' ] = c.replace( re , ' ' ) ;
	} ,
	
	/**
	 * @param HTMLElement
	 * @param string
	 * @param string
	 * @return void
	 */
	replaceClass: function( element , oldClassName , newClassName ) {
		this.removeClass( element , oldClassName ) ;
		this.addClass( element , newClassName ) ;
	} ,
	
	/**
	 * @param HTMLElement
	 * @return Object
	 */
	position: function( element ) {
		if ( element.parentNode === null ) {
			return false ;
        } ;
        
        var parent = element.offsetParent ;
        var pos    = { x:element.offsetLeft , y:element.offsetTop } ;
        
        while ( parent != null ) {
        	pos.x += parent.offsetLeft ;
        	pos.y += parent.offsetTop ;
        	
        	parent = parent.offsetParent ;
        } ;
		
		return pos ;
	} ,
	
	/**
	 * @return Object
	 */
	windowSize: function() {
		var size = { width:0 , height:0 } ;
		
		if ( window.innerHeight >= 0 ) {
			size.width  = window.innerWidth ;
			size.height = window.innerHeight ;
		} else if ( document.documentElement ) {
			size.width  = document.documentElement.clientWidth ;
			size.height = document.documentElement.clientHeight ;
		} else if ( document.body.clientHeight >= 0 ) {
			this.width  = document.body.clientWidth ;
			this.height = document.body.clientHeight ;
		} ;
		
		return size ;
	} ,
	
	/**
	 * @param string
	 * @param HTMLElement
	 * @return Node
	 */
	createNode: function( tagname , parent ) {
		var element = document.createElement( tagname ) ;
		parent.appendChild( element ) ;
		
		return new nl.xd.dom.Node( element ) ;
	} ,
	
	/**
	 * @param string
	 * @param boolean
	 * @return string
	 */
	createTag: function( tagname , close ) {
		var tag = '' ;
		
		if ( close ) {
			tag += '<' + tagname + '></' + tagname + '>' ;
		} else {
			tag += '<' + tagname + '/>' ;
		} ;
		
		return tag ;
	} ,
	
	/**
	 * @param string
	 * @return string
	 */
	getAttribute: function( element , attribute ) {
		if ( element[ attribute ] ) {
			return element[ attribute ] ;
		} else {
			return element.getAttribute( attribute ) ;
		} ;
	}
} ;
