// -- Standard functions
//http://4umi.com/web/javascript/array.htm

// Array.concat() - Join two arrays
if( typeof Array.prototype.concat==='undefined' ) {
	Array.prototype.concat=function(a){
		for(var i=0,b=this.copy();i<a.length;i++){
			b[b.length]=a[i];
		}
		return b;
	};
}

// Array.copy() - Copy an array
if(typeof Array.prototype.copy==='undefined'){
	Array.prototype.copy=function(){
		var a=[],i=this.length;
		while(i--){
			a[i]=typeof this[i].copy!=='undefined'?this[i].copy():this[i];
		}
		return a;
	};
}

// Array.pop() - Remove and return the last element of an array
if(typeof Array.prototype.pop==='undefined'){
	Array.prototype.pop=function(){
		var b=this[this.length-1];
		this.length--;
		return b;
	};
}

// Array.push() - Add an element to the end of an array, return the new length
if(typeof Array.prototype.push==='undefined'){
	Array.prototype.push=function(){
		for(var i=0,b=this.length,a=arguments,l=a.length;i<l;i++){
			this[b+i]=a[i];
		}
		return this.length;
	};
}

// Array.shift() - Remove and return the first element
if(typeof Array.prototype.shift==='undefined'){
	Array.prototype.shift=function(){
		for(var i=0,b=this[0],l=this.length-1;i<l;i++){
			this[i]=this[i+1];
		}
		this.length--;
		return b;
	};
}

// Array.slice() - Copy and return several elements
if(typeof Array.prototype.slice==='undefined'){
	Array.prototype.slice=function(a,c){
		var i,l=this.length,r=[];
		if(!c){c=l;}
		if(c<0){c=l+c;}
		if(a<0){a=l-a;}
		if(c<a){i=a;a=c;c=i;}
		for(i=0;i<c-a;i++){r[i]=this[a+i];}
		return r;
	};
}

// Array.splice() - Remove or replace several elements and return any deleted elements
if(typeof Array.prototype.splice==='undefined'){
	Array.prototype.splice=function(a,c){
		var i=0,e=arguments,d=this.copy(),f=a,l=this.length;
		if(!c){c=l-a;}
		for(i;i<e.length-2;i++){this[a+i]=e[i+2];}
		for(a;a<l-c;a++){this[a+e.length-2]=d[a-c];}
		this.length-=c-e.length+2;
		return d.slice(f,f+c);
	};
}

// Array.unshift() - Add an element to the beginning of an array
if(typeof Array.prototype.unshift==='undefined'){
	Array.prototype.unshift=function(){
		this.reverse();
		var a=arguments,i=a.length;
		while(i--){this.push(a[i]);}
		this.reverse();
		return this.length;
	};
}

// -- 4umi additional functions

// Array.forEach( function ) - Apply a function to each element
Array.prototype.forEach=function(f){
	var i=this.length,j,l=this.length;
	for(i=0;i<l;i++){
		if((j=this[i])){f(j);}
	}
};

// Array.indexOf( value, begin, strict ) - Return index of the first element that matches value
Array.prototype.indexOf=function(v,b,s){
	for(var i=+b || 0,l=this.length;i<l;i++){
		if(this[i]===v || s && this[i]==v){return i;}
	}
	return -1;
};

// Array.insert( index, value ) - Insert value at index, without overwriting existing keys
Array.prototype.insert=function(i,v){
	if(i>=0){
		var a=this.slice(),b=a.splice(i);
		a[i]=v;
		return a.concat(b);
	}
};

// Array.lastIndexOf( value, begin, strict ) - Return index of the last element that matches value
Array.prototype.lastIndexOf=function(v,b,s){
	b=+b || 0;
	var i=this.length;
	while(i-->b){
		if(this[i]===v || s && this[i]==v){return i;}
	}
	return -1;
};

// Array.random( range ) - Return a random element, optionally up to or from range
Array.prototype.random=function(r){
	var i=0,l=this.length;
	if(!r){
		r=this.length;
	}else if(r>0){
		r=r%l;
	}else {
		i=r;r=l+r%l;
	}
	return this[Math.floor(r*Math.random()-i)];
};

// Array.shuffle( deep ) - Randomly interchange elements
Array.prototype.shuffle=function(b){
	var i=this.length,j,t;
	while(i){
		j=Math.floor((i--)*Math.random());
		t=b && typeof this[i].shuffle!=='undefined'?this[i].shuffle():this[i];
		this[i]=this[j];
		this[j]=t;
	}
	return this;
};

// Array.unique( strict ) - Remove duplicate values
Array.prototype.unique=function(b){
	var a=[],i,l=this.length;
	for(i=0;i<l;i++){
		if(a.indexOf(this[i],0,b)<0){a.push(this[i]);}
	}
	return a;
};

// Array.walk() - Change each value according to a callback function
Array.prototype.walk=function(f){
	var a=[],i=this.length;
	while(i--){a.push(f(this[i]));}
	return a.reverse();
};

/*
getNodeName(xmldoc,duplicate)

Copyright 卜維丰
http://audi.tw

歡迎無償使用，在套用時，請勿移除本版本權告

取得子節點標籤名稱

輸入項:
	xmldoc		:xml文件
	duplicate	:boolean,允許重複項,預設為 true
輸出項:
	Array()
	以第一層子節點標籤名稱組成的陣列
*/

function getNodeName(xmldoc,duplicate){
	/*

	*/

	var d;
	var na=[];

	d=(typeof duplicate=='undefined')?true:duplicate;

	for (var i=0;i<xmldoc.childNodes.length;i++){
		if (xmldoc.childNodes[i].hasChildNodes()){
			na=na.concat(xmldoc.childNodes[i].tagName);
		}
	}

	na=(d)?na:na.unique();

	return na
}

/*
getNodeContent(xmldoc,key,label)
Copyright 卜維丰
http://audi.tw
歡迎無償使用，在套用時，請勿移除本版本權告
取得節點內容值
輸入項:
	xmldoc	:xml文件
	key	:標籤名稱
	label	:子節點屬性名稱,用於取得屬性值
輸出項:
	Array([a,b])
	a=標籤名稱, 或標籤中指定屬性值
	b=標籤字串值
	例:
	<product>
	<name value="產品">Sony Handy Cam</name>
	<price value="單價">21000</name>
	</product>
	getNodeContent(xml,'product') 回傳值為[name,Sony Handy Cam][price,21000]
	getNodeContent(xml,'product','value') 回傳值為[產品,Sony Handy Cam][單價,21000]
*/
function getNodeContent(xmldoc,key,label) {
	var na=[],va=[],l;
	var outstr='';
	key=(typeof key=='undefined')?getNodeName(xmldoc,false):key;

	for (var i=0;i<xmldoc.getElementsByTagName(key).length;i++){
		var xml=xmldoc.getElementsByTagName(key)[i];
		na=getNodeName(xml,false);	//必需是唯一值,因為接下來的動作,會依序讀出

		for (var j=0;j<na.length;j++){
			var xmlk=xml.getElementsByTagName(na[j]);
			for (var k=0;k<xmlk.length;k++){
				l=Math.max(va.length,va.length-1);
				if(typeof label!='undefined'){
					if(typeof xmlk[k].getAttribute(label)!=null && typeof xmlk[k].getAttribute(label)!=''){
						va[l]=[xmlk[k].getAttribute(label),xmlk[k].childNodes[0].nodeValue];
					}else{
						va[l]=[na[j],xmlk[k].childNodes[0].nodeValue];
					}
				}else{
					va[l]=[na[j],xmlk[k].childNodes[0].nodeValue];
				}
				outstr+=va[l]+'\n';
			}
		}
	}
	//alert(outstr);
	//xmlToTable(va);
	return va
}