Ysf = {Dom:{}};

Ysf.Dom.quiet = false;

Ysf.Dom.name = function ( e ) {
	return e.nodeName + (e.id ? ' #' + e.id : '' ) + (e.className ? ' .' + e.className : '');
}

Ysf.Dom.getAllPreviousSiblings = function ( e ) {
	var ret = [];
	var ptr = e;
	while ( ptr = ptr.previousSibling ) {
		ret.push ( ptr );
	}
	return ret;
}

Ysf.Dom.getAllNextSiblings = function ( e ) {
	var ret = [];
	var ptr = e;
	while ( ptr = ptr.nextSibling ) {
		ret.push ( ptr );
	}
	return ret;
}

Ysf.Dom.getAllSiblings = function ( e ) {
	return e.parentNode.childNodes;
}

Ysf.Dom.FindClause = function ( type, value ) {
	this.type = type;
	this.value = value;
}

Ysf.Dom.FindClause.prototype.match = function ( element ) {
	var ret = false;
	if ( element.nodeType == 1 ) {
		switch ( this.type ) {
			case 'tagName': case 'nodeName':
				ret = ( element.nodeName.toLowerCase () == this.value.toLowerCase () );
			break;
			case 'className':
				ret = ( Element.hasClassName ( element, this.value ) );
			break;
		}
	}
	return ret;
}

Ysf.Dom.FindClause.prototype.toString = function () {
	return 'FindClause [' + this.type + '=' + this.value + ']';
}

Ysf.Dom.findAll = function ( list, clause ) {
	var ret = $A(list).findAll ( function ( e ) { return clause.match(e); } );
	return ret;
}

Ysf.Dom.find = function ( list, clause ) {
	var ret = $A(list).find ( function ( e ) { return clause.match(e); } );
	if ( !ret && !Ysf.Dom.quiet) { 
		alert ( 'Not found: ' + clause.toString () );
	}
	return ret;
}

Ysf.Dom.findFirstSiblingByClassName = function ( e, className ) {
	return Ysf.Dom.findFirstChildByClassName ( e.parentNode, className );
}

Ysf.Dom.findFirstSiblingByTagName = function ( e, tagName ) {
	return Ysf.Dom.findFirstChildByTagName ( e.parentNode, tagName );
}

Ysf.Dom.findFirstChildByClassName = function ( e, className, override ) {
	return Ysf.Dom.findFirstChild ( e, new Ysf.Dom.FindClause ( 'className', className ) );
}

Ysf.Dom.findFirstChildByTagName = function ( e, tagName, override ) {
	return Ysf.Dom.findFirstChild ( e, new Ysf.Dom.FindClause ( 'tagName', tagName ) );
}

Ysf.Dom.findFirstChild = function ( e, clause ) {
	return Ysf.Dom.find ( e.childNodes, clause );
}

Ysf.Dom.findPreviousSibling = function ( e, clause ) {
	return Ysf.Dom.find ( Ysf.Dom.getAllPreviousSiblings ( e ), clause );
}

Ysf.Dom.findPreviousSiblingByClassName = function ( e, className ) {
	return Ysf.Dom.findPreviousSibling ( e, new Ysf.Dom.FindClause ( 'className', className ) );
}

Ysf.Dom.findPreviousSiblingByTagName = function ( e, tagName ) {
	return Ysf.Dom.findPreviousSibling ( e, new Ysf.Dom.FindClause ( 'tagName', tagName ) );
}

Ysf.Dom.findNextSibling = function ( e, clause ) {
	return Ysf.Dom.find ( Ysf.Dom.getAllNextSiblings ( e ), clause );
}

Ysf.Dom.findSibling = function ( e, clause ) {
	return Ysf.Dom.find ( Ysf.Dom.getAllSiblings ( e ), clause );
}

Ysf.Dom.findNextSiblingByClassName = function ( e, className ) {
	return Ysf.Dom.findNextSibling ( e, new Ysf.Dom.FindClause ( 'className', className ) );
}

Ysf.Dom.findNextSiblingByTagName = function ( e, tagName ) {
	return Ysf.Dom.findNextSibling ( e, new Ysf.Dom.FindClause ( 'tagName', tagName ) );
}

Ysf.Dom.findDescendant = function ( e, clause ) {
	return Ysf.Dom.find ( e.getElementsByTagName('*'), clause );
}

Ysf.Dom.findFirstDescendantByTagName = function ( e, tagName ) {
	return Ysf.Dom.findDescendant ( e, new Ysf.Dom.FindClause ( 'tagName', tagName ) );
}

Ysf.Dom.findFirstDescendantByClassName = function ( e, className  ) {
	return Ysf.Dom.findDescendant ( e, new Ysf.Dom.FindClause ( 'className', className ) );
}

Ysf.Dom.findFirstAncestor = function ( e, clause ) {
	var ptr = e.parentNode;
	do {
		if ( clause.match ( ptr ) ) {
			return ptr;
		}
	} while ( ptr = ptr.parentNode );
	return null;
}

Ysf.Dom.findFirstAncestorByTagName = function ( e, tagName ) {
	return Ysf.Dom.findFirstAncestor ( e, new Ysf.Dom.FindClause( 'tagName', tagName ) );
}

Ysf.Dom.findFirstAncestorByClassName = function ( e, className ) {
	return Ysf.Dom.findFirstAncestor ( e, new Ysf.Dom.FindClause( 'className', className ) );
}

Ysf.showIf = function ( condition, element ) {
	Element[condition?'show':'hide']( element );
} 

Ysf.toggleClass = function ( e, className ) {
	return Ysf.toggleClassIf ( !Element.hasClassName(e,className), e, className );
}

Ysf.toggleClassIf = function ( condition, e, className ) {
	if ( condition ) {
		Element.addClassName ( e, className );
	} else {
		Element.removeClassName ( e, className );
	}
}

Ysf.toggle = function ( e ) {
	Ysf.showIf ( !Element.visible(e), e );
}

$next = Ysf.Dom.findNextSiblingByTagName;
$prev = Ysf.Dom.findPreviousSiblingByTagName;
$ancestor = Ysf.Dom.findFirstAncestorByTagName;
$child = Ysf.Dom.findFirstChildByTagName;
$sibling = Ysf.Dom.findFirstSiblingByTagName;
$descendant = Ysf.Dom.findFirstDescendantByTagName;

$next_c = Ysf.Dom.findNextSiblingByClassName;
$prev_c = Ysf.Dom.findNextSiblingByClassName;
$ancestor_c = Ysf.Dom.findFirstAncestorByClassName;
$child_c = Ysf.Dom.findFirstChildByClassName;
$sibling_c = Ysf.Dom.findFirstSiblingByClassName;
$descendant_c = Ysf.Dom.findFirstDescendantByClassName;

Ysf.Event = {};
Ysf.Event.offsetX = function ( event, offsetElement ) {
	return event.offsetX | event.layerX;
	//return Event.pointerX ( event ) + Position.realOffset(offsetElement )[0] - Position.cumulativeOffset(offsetElement)[0]; 
} 

Ysf.Event.offsetY = function ( event, offsetElement ) {
	return event.offsetY | event.layerY;
	//return Event.pointerX ( event ) + Position.realOffset(offsetElement )[1] - Position.cumulativeOffset(offsetElement)[1]; 
}
