//##copyright
//function onContent(f){//(C)webreflection.blogspot.com
//function getImgSize(dImg) from http://www.hedgerwow.com/360/dhtml/dom-get-natural-width.html
//copyright##
/*
* dom_suite.js
*
* Shorthand function for creating DOM Elements
* depends on yui's dom
*
*
*/

// finds iframe window: the window object of given IFrame
function ifWin(iframe)
{
	var win = null;
	if (iframe.contentWindow) { // IE5.5+, Mozilla, NN7
		win = iframe.contentWindow;
	} else if (iframe.contentDocument) { // NN6, Konqueror
		win = iframe.contentDocument.defaultView;
	} else if (iframe.Document) { // IE5
		win = iframe.Document.parentWindow;
	} else {
		//
	}
	return win;
}

// find children
// e: starting dom
// d: depth
// criteria: attribute matching
// className: class
function fc2(e, d, criteria, className)
{
	if(d!=null && d.constructor!=Number){
		throw 'Incorrect calling syntax for fc2: 2nd parameter [depth] must be number!';
	}

	var ret = [];
	var cs = e.childNodes;
	for(var i=0, e=cs.length; i<e; i++){
		if(cs[i].nodeType == 3) continue;
		var pass = true;
		if (className &&
			(className.constructor==RegExp?
				!(className.test(cs[i].className)):
				!(cs[i].className==className)))
			continue;

		for(var field in criteria){
			value = criteria[field];
			switch (value.constructor) {
			case Boolean:
				attr = cs[i][field] || cs[i].getAttribute(field);
				if (value && attr || !value && !attr) continue;
				break;
			case RegExp:
				attr =  cs[i].getAttribute(field);
				if (value.test(attr)) continue;
				break;
			default:
				attr =  cs[i].getAttribute(field);
				if (attr == value) continue;
			}
			pass = false;
			break;
		}

		if(pass){
			ret[ret.length] = cs[i];
		}
	}
	if(d>1){
		for(var i=0, e=cs.length; i<e; i++){
			ret = ret.concat(fc2(cs[i], d-1, criteria, className));
		}
	}
	return ret;
}

/**
 * find child / children (array) with tag
 * e : dom
 * t : tag
 * criteria : attribute matching
 * className : name of class to be searched (support RegExp)
 * first: if true, return the first result
 */
function fc(e, t, criteria, className, first)
{
	var cs = e.getElementsByTagName(t);
	var ret = new Array();
	if(criteria || className){
		for(var i=0, e=cs.length; i<e; i++){
			if(cs[i].nodeType == 3) continue;
			var pass = true;
			if (className &&
				(className.constructor==RegExp?
					!(className.test(cs[i].className)):
					!(cs[i].className==className)))
				continue;
			for(var field in criteria){
				value = criteria[field];
				switch (value.constructor) {
				case Boolean:
					attr = cs[i][field] || cs[i].getAttribute(field);
					if (value && attr || !value && !attr) continue;
					break;
				case RegExp:
					attr =  cs[i].getAttribute(field);
					if (value.test(attr)) continue;
					break;
				default:
					attr =  cs[i].getAttribute(field);
					if (attr == value) continue;
				}
				pass = false;
				break;
			}
			if(pass){
				if (first) return cs[i];
				ret[ret.length] = cs[i];
			}
		}
	}
	else{
		ret = cs;
	}

	return first?ret[0]:ret;
}

// find parent with given tag t
// criteria contains attribute->value pairs for matching
// value may be a RegExp
function fp(e, t, criteria, className)
{
	//var p = e.parentNode;
	var p = e;
	var attr, value;
	t && (t = t.toUpperCase());
	while (p && p!=document && p.getAttribute){
		var pass = (!t || (p.tagName == t));
		if (pass && className &&
			(className.constructor==RegExp?
				!(className.test(p.className)):
				!(p.className==className))){
					pass = false;
				}
		if(pass && criteria){
			for(var field in criteria){
				//attr =  p[field];
				value = criteria[field];
				switch (value.constructor) {
				case Boolean:
					attr =  p[field] || p.getAttribute(field);
					if (value && attr || !value && !attr) continue;
					break;
				case RegExp:
					attr =  p.getAttribute(field);
					if (value.test(attr)) continue;
					break;
				default:
					attr =  p.getAttribute(field);
					if (attr == value) continue;
				}
				pass = false;
				break;
			}
		}
		if(pass){
			return p;
			break;
		}
		p = p.parentNode;
	}
	return null;
}

// return controller for an element
// search up the dom hierarchy until an element having portletObj is set
// moved to IqubeController!
//function getController(e){
//	return fp(e, null, {portletObj:true}).portletObj.getController();
//}

function ce(e){return document.createElement(e);}

/*
* function cex
*
* Shorthand function for creating DOM Elements
*
* The first parameter is the name of the element to create.
* The second parameter is a Javascript object literal used to
* initialize the elements once created.
*
* Returns the DOM Element created
*
* Example:
*   var a = cex("DIV", {onmouseover:foo, name:'div1', id:'main', innerHTML: 'content'});
*/
function cex(e, x){
	var a = document.createElement(e);
	for (var prop in x){
		if (typeof x[prop] == 'object') {
			for (var y in x[prop]) {
				eval('a.'+prop+'.'+y+'=x.'+prop+'.'+y+';');
			}
		} else {
			a[prop] = x[prop];
		}
	}
	return a;
}

// shorthand for createTextNode
function ctn(t) {return document.createTextNode(t);}
/*
* function ge
*
* Shorthand function for document.getElementById(i)
*/
function ge(i){return document.getElementById(i);}

Function.prototype.apply2all = function(a) {
	for (var i=0,e=a.length;i<e;i++) {
		this(a[i], i, e);
	};
}

/*------------------------------*/

function gc(e, i) {return e.childNodes[i];}

/* function ra
* shorthand for removeAttributes
*/
function ra(){
	if (ra.arguments.length > 1){
		var el = ra.arguments[0]; // element
		for (i=1; i<ra.arguments.length; i++){
			if (arguments[i])
			el.removeAttribute(ra.arguments[i]);
		}
		return el;
	} else {
		return null;
	}

}

function ib(a,b) {return b.parentNode.insertBefore(a,b);}
function rn(a) {return a.parentNode.removeChild(a);}
function rc(n,o) {return o.parentNode.replaceChild(n,o);}
function ia(a,b){
	if(b.nextSibling){
		return b.parentNode.insertBefore(a,b.nextSibling);
	}
	else{
		b.parentNode.appendChild(a);
	}
}
// remove empty child, return first child
function rec(a) {
		if (a.firstChild && a.firstChild.nodeType==3) {
		    for (var i=a.childNodes.length; i>0; i--) {
		    	var n = a.childNodes[i-1]; // must work from the back
		    	//YAHOO.log('Test = '+!/\S/.test(n.nodeValue)+' i = '+i+'a.childNodes.length = '+a.childNodes.length+' innerHTML = '+n.nodeValue);
		    	if (n.nodeType == 3 && !/\S/.test(n.nodeValue)) rn(n);
		    }
		}
	    return a.firstChild;
}

/*
* function ac
*
* Shorthand function for appendChild
*
* Accepts an arbitrary number of elements as parameters and appends
* the 2nd and later elements to the first element.  Returns the first
* object in the list after appends.  Useful in chains (see Example)
*
* Example: ac( house, ac(roof, shingles), ac(floor, ac(tiles, grout)))
*/
function ac(){
	if (ac.arguments.length > 1){
		var a = ac.arguments[0];
		for (i=1; i<ac.arguments.length; i++){
			if (arguments[i])
			a.appendChild(ac.arguments[i]);
		}
		return a;
	} else {
		document.body.appendChild(ac.arguments[0]);
		return ac.arguments[0];
	}

}

// append tree (build dom from array tree)
// this is done to avoid potential DOM Insertion Order Leak according to
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/dnwebgen/ie_leak_patterns.asp
// usage:
// 	at([root, child1, [child2, grandchild1, grandchild2, [grandgrandchild1, ....]]]);
// return the first item on the array
function at(a) {
	if (a.constructor == Array) {
		var b = a[0];
		var c;
		for (var i=1, e = a.length;i<e;i++) {
			c = a[i];
			if (!c) continue;
			if (c.constructor == Array) {
				b.appendChild(c[0]);
				at(c);
			} else {
				b.appendChild(c);
			}
		}
		return b;
	} else {
		document.body.appendChild(a);
		return a;
	}
}




/*function getXY2(el, which) {
	var x = el.offsetLeft-el.scrollLeft;
	var y = el.offsetTop-el.scrollTop;
    if (which) {
    	x += el.offsetWidth * (which % 3) / 2;
    	y += el.offsetHeight * parseInt(which /3 ) / 2;
    }
	el = el.offsetParent;
    while (el) {
        x += el.offsetLeft-el.scrollLeft;
        y += el.offsetTop-el.scrollTop;
		el = el.offsetParent;
    }


	return {x: x, y: y}
}*/

//Copyright (c) 2006 Yahoo! Inc. All rights reserved.
/**
 * @class Provides helper methods for DOM elements.
 */
/**
* function getXY()
*
* Returns the position (relative to page) of any element as an object.
* add support to calculate which corner to return 0-8, 0 = upper left
* Typical usage:
* var pos = getXY(object);
* 0 1 2
* 3 4 5
* 6 7 8
*/
function getXY(el, which)
{
	var xy = YuDom.getXY(el);
	if (which) {
		xy[0] += el.offsetWidth * (which % 3) / 2;
		xy[1] += el.offsetHeight * parseInt(which /3 ) / 2;
	}
	return {x:xy[0],y:xy[1]};
}

// * Returns the corner positions (x1,x2,y1,y2) (relative to page) of any element as an object.
function getCorners(el) {
	var pos = getXY(el);
	var w = el.offsetWidth;
	var h = el.offsetHeight;
	return {x: pos.x, x2: pos.x+w, y: pos.y, y2: pos.y+h};
}
/**
* function geEvttXY()
*
* Returns the position (relative to page) of an event
*
*/
function getEvtXY(e)
{
	var pos = {x:0, y:0};
	if (e.pageX) {
  		pos = {x:e.pageX, y:e.pageY}
	} else {
		pos = {x:e.clientX + document.body.scrollLeft - document.body.clientLeft,
		y:e.clientY + document.body.scrollTop - document.body.clientTop};
		//return pos;
		// include html element space, if applicable
		if (document.body.parentElement && document.body.parentElement.clientLeft) {
			var bodParent = document.body.parentElement;
			pos.x += bodParent.scrollLeft - bodParent.clientLeft;
			pos.y += bodParent.scrollTop - bodParent.clientTop;
		}
	}

    return pos;

}

function clone(myObj)
{
	if(typeof(myObj) != 'object') return myObj;
	if(myObj == null) return myObj;
	var myNewObj = new myObj.constructor();
	for(var i in myObj) {
		if (typeof myObj[i] == 'object') {
			myNewObj[i] = clone(myObj[i]);
		} else {
			myNewObj[i] = myObj[i];
		}
	}
	return myNewObj;
}

/* #0000062 this section is trying to fix the IE's handling of encoded url - using a.href will decode url incorrectly (should return raw url).
   now use outerHTML to extract raw href */
/* updated to use getAttribute(href,2) */
function getRawHref(a)
{
	return a.getAttribute('href',2);
/*	if (a.outerHTML) {
		var url;
		var matches = a.outerHTML.match(/href=['"]([^"']*?)["']/);
		if (!matches || !(url = matches[1])) return false;
		return url;
	} else {
		return a.href;
	}*/
}

// force reloading of css file - filename is searched as "contain". If no filename is given, all css will be reloaded
// delquery is the name of the query to be deleted / replaced (e.g. groupid) - no need to include =xxx part
// addquery is the whole query to be added, e.g. groupid=yyy
function reloadCSS(filename, delquery, addquery)
{
	var a=document.getElementsByTagName('link');
	for(var i=0;i<a.length;i++){
		var s=a[i];
		if(s.rel.toLowerCase().indexOf('stylesheet')>=0 && s.href && (!filename || s.href.toLowerCase().indexOf(filename) >=0)) {
			var h=s.href.replace(/(&|\?)forceReload=\d+/,'');
			if (delquery) {
				var regex = new RegExp('(&|\\?)'+delquery+'=.*?$'); // if last item
				h= h.replace(regex,'');
				var regex = new RegExp('(&|\\?)'+delquery+'=.*?&'); // if middle item
				h = h.replace(regex,'$1');
			}
			if (addquery) {
				h = h+(h.indexOf('?')>=0?'&':'?')+addquery;
			}
			h =  h+(h.indexOf('?')>=0?'&':'?')+'forceReload='+(new Date().valueOf());
//			log('reloadCSS = original:'+s.href+'  new:'+h);
			s.href = h;

		}
	}
}

// test whether an event happens inside an element
function happensInElement(event, element){
	var etarget = YuEvent.getTarget(event);
	if (YuDom.isAncestor(element, etarget)) return true;

	var xy = getEvtXY(event);
	var corners = getCorners(element);
//	YAHOO.log(JSON.stringify({xy:xy,corners:corners},true),'DBG','Dom_suite');
	return xy.x >= corners.x && xy.x <= corners.x2 && xy.y >= corners.y && xy.y <= corners.y2;
};

var op = /opera 5|opera\/5/i.test(navigator.userAgent) && window.opera;
var ie = !op && /msie/i.test(navigator.userAgent);	// preventing opera to be identified as ie
var mz = !op && /mozilla\/5/i.test(navigator.userAgent);	// preventing opera to be identified as mz

//function applyPNGsrc(parent) {
//	var img = fc(parent, 'img', null, 'pngbg');
//	for (var i in img) {
//		var el = img[i];
//		if (YuDom.getStyle(el,'display') != 'none') {
//			var bg = YuDom.getStyle(el,'background-image');
//			var matches = bg && bg.match(/url\(\s*['"]?(.+?)\s*['"]?\)/);
//			if (matches) {
//				el.src = matches[1];
//			} else {
//				el.src = '';
//			}
//		}
//	}
//}

//if (ie) {
//	function applyPNGBackground(dParent)
//	{
//		if (dParent.firstChild.tagName != 'png:rect') {
//			var dummy = cex('div', {innerHTML: '<png:rect style="behavior: url(#default#vml); height: 1%; display: block; z-index: -1;"></png:rect>'});
//			var dRect = dummy.firstChild;
//			ac(dParent, dRect);
//			for (var i=0, e=dParent.childNodes.length; i<e-1;i++) {
//				ac(dRect, dParent.firstChild);
//			}
//			//dRect.style.behavior ='url(#default#vml)';
//			//dRect.runtimeStyle.behavior ='url(#default#vml)';
//
//			var src = dParent.currentStyle.backgroundImage.split('"')[1];
//			dRect.stroked = 'f';
//
//			switch(dParent.currentStyle.backgroundRepeat.toLowerCase())
//			{
//				case 'repeat':;
//				dRect.filled = 't';
//				dRect.fill.src = src ;
//				dRect.fill.type = 'tile' ;	//type, string, "solid", "solid", "tile", "pattern", "frame".
//				dParent.style.backgroundImage = 'url()';
//				break;
//				default:;
//				dRect.filled = 'f';
//				dParent.style.backgroundImage = 'url()';
//				dRect.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "',sizingMethod='crop')";
//				break;
//			};
//		}
//	}
//}

// http://www.hedgerwow.com/360/dhtml/dom-appendHTML.html
//function appendHTML(dEl, sHTML , bAfterBegin)
//{
//	var d1stChild ;
//	if( ! ( d1stChild = dEl.firstChild ) )
//	{
//		dEl.innerHTML = sHTML;
//		return;
//	}
//
//	bAfterBegin = ( !!bAfterBegin )||  false;
//
//	if(dEl.insertAdjacentHTML)
//	{
//		bAfterBegin = bAfterBegin?'AfterBegin':'BeforeEnd';
//		dEl.insertAdjacentHTML(bAfterBegin,	sHTML );
//	}
//	else
//	{
//		try
//		{
//			var r = dEl.ownerDocument.createRange();
//			r.setStartBefore(dEl);
//			var dSnippet = r.createContextualFragment(sHTML);
//			if(bAfterBegin)
//			{
//				dEl.insertBefore(dSnippet ,d1stChild );
//			}
//			else
//			{
//				dEl.appendChild(dSnippet);
//			}
//		}
//		catch(err)
//		{
//			var tempNode = document.createElement('div');
//			tempNode.innerHTML = sHTML ;
//			var c ;
//			if(bAfterBegin)
//			{
//				while(c = tempNode.firstChild )
//				{
//					dEl.insertBefore(c , d1stChild);
//				}
//			}
//			else
//			{
//				while(c = tempNode.firstChild )
//				{
//					dEl.appendChild(c);
//				}
//			};
//			tempNode = null;
//
//		}
//
//	}
//}

// set left of given element to the center of parent container
function centerParent(el){
	var parent = el.parentNode;
	if(!parent) return;
	var pl = parseInt(parent.style.paddingLeft||'0');
	var pr = parseInt(parent.style.paddingRight||'0');
	el.style.left = (parent.clientWidth - pl - pr - el.clientWidth) / 2 + 'px';
}
// set top of given element to the middle of parent container
function middleParent(el){
	var parent = el.parentNode;
	if(!parent) return;
	var pl = parseInt(parent.style.paddingTop||'0');
	var pr = parseInt(parent.style.paddingBottom||'0');
	el.style.top = (parent.clientHeight - pl - pr - el.clientHeight) / 2 + 'px';
}


// capture events
// elSrc: elements that initiate event
// sEvent: the event respond to, e.g., 'click'
// fHandler: handler function
//   fHandler(e): this: the dom element that initializes the event
function Capture(elSrc, sEvent, fHandler)
{
	var events = sEvent.split('|');
	var handler = function(e){
		e = YuEvent.getEvent(e);
		YuEvent.stopEvent(e);
		fHandler.call(YuEvent.getTarget(e), e, YuEvent.getTarget(e));
		return false
	};

	// stop capture
	var stop = function(){
		if(elSrc.releaseCapture){
			for(var i=0; i<events.length; i++){
				YuEvent.removeListener(elSrc, events[i], handler);
			}
			elSrc.releaseCapture();
		}
		else if(document.addEventListener){
			for(var i=0; i<events.length; i++){
				document.removeEventListener(events[i], handler, true);
			}
		}
		else{
			// do nothing
		}
		YuEvent.removeListener(elSrc, 'keydown', escape);
		elSrc = null;
		start = null;
		stop = null;
		events = null;
		this.start = null;
		this.stop = null;
		fHandler = null;
		handler = null;
	};
	// start capture
	var start = function(){
		if(elSrc.setCapture){
			// ie
			for(var i=0; i<events.length; i++){
				YuEvent.addListener(elSrc, events[i], handler);
			}
			elSrc.setCapture();
		}
		else if(document.addEventListener){
			// assume support dom level 3 addEventListener
			// use document.addEventListener
			// elSrc is ignored here
			for(var i=0; i<events.length; i++){
				document.addEventListener(events[i], handler, true);
			}
		}
		else{
			// no action
		}
	};

	this.start = start;
	this.stop = stop;
}

var addStyleRule = document.styleSheets[0].addRule ?
	 function (selector, style) {
		return document.styleSheets[0].addRule(selector, style, 0);
	}:
	function (selector, style) {
		return document.styleSheets[0].insertRule(selector+ " {"+style+"}", 0);
	};

var removeStyleRule = document.styleSheets[0].removeRule ?
	function(index) {
		document.styleSheets[0].removeRule(index);
	}:
	function(index) {
		document.styleSheets[0].removeRule(index);
	};

	
function onContent(f){//(C)webreflection.blogspot.com
var a=onContent,b=navigator.userAgent,d=document,w=window,c="onContent",e="addEventListener",o="opera",r="readyState",
s="<scr".concat("ipt defer src='//:' on",r,"change='if(this.",r,"==\"complete\"){this.parentNode.removeChild(this);",c,".",c,"()}'></scr","ipt>");
a[c]=(function(o){return function(){a[c]=function(){};for(a=arguments.callee;!a.done;a.done=1)f(o?o():o)}})(a[c]);
if(d[e])d[e]("DOMContentLoaded",a[c],false);
if(/WebKit|Khtml/i.test(b)||(w[o]&&parseInt(w[o].version())<9))(function(){/loaded|complete/.test(d[r])?a[c]():setTimeout(arguments.callee,1)})();
else if(/MSIE/i.test(b))d.write(s);
};
	
// fix the selected item of an selected box
// E.g. 1,
//  <select value="2">
//    <option value="1">1</option>
//    <option value="2">2</option>
//  </select>
//
// Result:
//  <select value="2">
//    <option value="1">1</option>
//    <option value="2" selected>2</option>
//  </select>
//
// E.g. 2,
//  <select>
//    <option value="1">1</option>
//    <option value="2" selected>2</option>
//  </select>
//
// Result:
//  <select value="2">
//    <option value="1">1</option>
//    <option value="2" selected>2</option>
//  </select>
//
// the VALUE attribute in the select tag take higher priority
function fixSelect(el)
{
	var value = el.getAttribute('m_value');
	if(value!=''){
		for(var i=0; i<el.options.length; i++){
			if(el.options[i].value == value){
				el.options[i].selected = true;
				break;
			}
		}
	}
}

// from http://www.hedgerwow.com/360/dhtml/dom-get-natural-width.html
function getImgSize(dImg)
{
	var size  = [-1,-1];
	if(dImg.naturalWidth != null)
	{
		size[0] = dImg.naturalWidth;
		size[1] = dImg.naturalHeight;
	}
	else if(dImg.runtimeStyle)
	{
		dImg.runtimeStyle.width= 'auto';
		dImg.runtimeStyle.height= 'auto';
		dImg.runtimeStyle.borderWidth= '0';
		dImg.runtimeStyle.padding= '0';
		size[0] = dImg.offsetWidth;
		size[1] = dImg.offsetHeight;
		dImg.runtimeStyle.width= '';
		dImg.runtimeStyle.height= '';
		dImg.runtimeStyle.borderWidth= '';
		dImg.runtimeStyle.padding= '';
	}else 
	{
		
		var dImgBk = dImg.cloneNode(true);
		dImg.className = '';
		dImg.style.width = 'auto !important';
		dImg.style.height = 'auto !important';
		dImg.style.borderWidth= '0 !important';
		dImg.style.padding= '0 !important';
		dImg.removeAttribute('width');
		dImg.removeAttribute('height');
		
		size[0] = dImg.width;
		size[1] = dImg.height;

		dImg.setAttribute('width' , dImgBk.getAttribute('width') );
		dImg.setAttribute('height', dImgBk.getAttribute('height') );


		dImg.style.width = dImgBk.style.width ; 
		dImg.style.height = dImgBk.style.height ; 
		dImg.style.padding = dImgBk.style.padding ; 
		dImg.style.borderWidth=  dImgBk.style.borderWidth ; 
		dImg.style.className = dImgBk.style.className ; 
		
	};

	return(size);
}